VBA:如何.结束 (xlup)。行在合并区域上的行为(已编辑)

VBA : How .End(xlup).Row behave on merged ranges (edited)

提问人:Tounn 提问时间:10/10/2023 最后编辑:Tounn 更新时间:10/10/2023 访问量:66

问:

这就是我现在所处的情况。我有以下函数调用:

Call function_1(name_sheet)
Call check_sheet_exist(name_sheet)
Call function_3(name_sheet)

如果条件为 true,并且此条件处于循环中,则调用此函数。在这个循环的开头,我有.因此,使用此工作表调用,并对该工作表进行操作,这就是我想要的。然后在函数中,我这样做:Workbooks(main).Worksheets(mask_1).Activatefunction_1check_name_sheet

Windows(main).Activate
For Each check_sheet In Workbooks(secondary).Sheets
    'some code
Next check_sheet
Workbooks(main).Sheets(mask1).activate '(mask2 can also be activated depending on what parameter is passed)

现在您已经了解了上下文,问题来了。在我尝试这样做:function_3

Workbooks(secondary).Sheets(name_sheet).Activate 'name_sheet passed as parameters
MsgBox Range("AQ100").End(xlUp).Row

我等待的值是 21,但我得到的是 19。这是因为代码搜索工作表中的最后一个空行。但是我不知道问题出在哪里,因为我已经用第一行指定了要搜索的工作表......MsgboxWorkbooks(main).Sheets(mask1)

我尝试打印我使用的变量的每个值,一切都已定义且正确。我也尝试过这个:function_3

Msgbox Workbooks(secondary).Sheets(name_sheet).Range("AQ100").End(xlUp).Row

name_sheet包含函数复制的名称,因此工作表显然位于工作簿中。工作簿已打开,确实存在,并且工作表具有正确的名称。check_sheet_exist

我唯一看到的可能是Windows(main)。激活这是我问题的目的,windows.activate是否拒绝工作簿的更改?

编辑:

这是我创建工作簿的函数:secondary

Dim secondary as New Workbook 'outside the function

Sub example ()

Set new_file = Workbooks.Add
With new_file
    .SaveAs Filename:=secondary
End With
secondary = ActiveWorkbook.name

End Sub

这是调用上述 3 个函数的 main 函数:

For i = 1 To Collection_1.Count
 For j = 1 To 5  
  Workbooks(main).Worksheets(mask_1).Activate
   If Collection_1(i).Length(j) = 5 Then
            Call function_1(name_sheet)
            Call check_sheet_exist(name_sheet)
            Call function_3(name_sheet)
   End If

Function_1不修改活动工作簿或活动工作表。

这是为什么最后一行应该是 21 的图像:

Excel VBA 循环

评论

0赞 FaneDuru 10/10/2023
首先,至少在我看来,你的代码设计方式并不是最好的。选择、激活只会消耗 Excel 资源,而不会带来任何好处,并且可能会造成混淆。例如,与其后跟,不如声明 ,然后 。我的意思是完全限定使用的范围。如果该工作表存在,则很可能在错误的工作簿上工作......Workbooks(secondary).Sheets(name_sheet).ActivateMsgBox Range("AQ100").End(xlUp).RowDim wsSec as WorksheetSet wsSec = Workbooks(secondary).Sheets(name_sheet)MsgBox wsSec.Range("AQ100").End(xlUp).Rowcheck_sheet_exist
0赞 VBasic2008 10/10/2023
你为什么不分享整个东西(包括功能)?另外,让我们知道哪个工作簿包含此代码。
1赞 CHill60 10/10/2023
引用:“我计划在代码工作后对其进行简化和优化”——有时第一次就以正确的方式做是它工作的原因!引用:“代码很长,并不是所有的东西都对这个特定问题有用”——但你分享的内容不足以说明这个问题的上下文。发布包含示例数据的最小代码,以便我们重现问题
1赞 Tounn 10/10/2023
@CHill60 好吧,我只是认为关于 SO 的问题需要简短,但我将解释所有内容
2赞 Notus_Panda 10/10/2023
最后一行=最后一行,里面有一些东西(在你的情况下应该是20?),而不是“最后一行有一个空单元格”,你能分享你的最后一行的屏幕截图吗(在左边行号的工作表中),你可以为此隐藏其他列。这里可能只是一个误解。

答:

2赞 Notus_Panda 10/10/2023 #1

想象一下我的测试表:

enter image description here

由于您的问题是合并了单元格,并且对最后一行之后的下一个空行有误解:

Sub nextEmptyRow()
    Dim lRow As Long
    lRow = ActiveSheet.Range("B" & Rows.Count).End(xlUp).Row
    Debug.Print lRow 'gives 9
    Dim rng As Range
    Set rng = ActiveSheet.Range("B" & lRow)
    Debug.Print rng.Offset(1).Row 'this is the actual next empty row
    'gives 11
End Sub

偏移量(我自己测试过这一点,实际上知道这一点)考虑了合并的单元格,因此它比合并单元格的最后一行更远 1 个。

就你而言,那就是:

Msgbox Workbooks(secondary).Sheets(name_sheet).Range("AQ100").End(xlUp).Offset(1).Row

评论

0赞 Tounn 10/10/2023
我认为我是地球上最脑残的开发者。因为我合并了 Cells,所以原来的值现在在 .由于混乱,我会给我最后一行,没有任何价值,这是完全错误的(我知道)。所以我预计是 21 岁,但正确的输出实际上是 19 岁。我不知道是什么导致了我这种困惑,但感谢上帝,我意识到了“孤独”。我想我真的很累,因为这太愚蠢了。很抱歉浪费时间,感谢您的耐心和帮助。AH19Range("AH19:AI20")End(xlup).Row
2赞 Notus_Panda 10/10/2023
没必要说那么多自欺欺人,每个人都会犯错。不客气,希望你能尽快睡一觉。
0赞 Tounn 10/10/2023
是的,我仍然很糟糕,但有趣的是,代码提醒我们,即使我们有能力做到最好,有时我们也有能力做到最坏。