如何在Excel VBA中将值从一个子项传递给另一个子项

在我的macros中,我有一个子程序(使用for循环)遍历表中的行,并根据列S中的内容在列V中写入注释。在此循环中,它还计算它显示“New “在列S中。现在我想把这个值传递给主macros,并下载到另一个子例程中。 我该怎么做,或者我的方法在这里是错的?

如果我理解正确,通常不可能从excel VBA中返回subs的值,但是你可以从函数中获得。 但是我不认为这里有一个函数是适合的(我可能会误解函数如何在VBA中工作,或者没有意识到它们的全部潜力)。

那么我该如何将variables/值从sub走私到另一个呢? 唯一的selectGlobalPublic宣言?

这是我的代码的一个非常粗略的例子:

 Sub MainMacro () Call CommentSub Call NumberOfRowsToCopy End sub Sub CommentSub Dim Counter As Integer For Counter = 1 to 500 If Cells(Counter, "S") = "New" Then NewOrderLineCounter = NewOrderLineCounter + 1 Cells(Counter, "V").Select ActiveCell.FormulaR1C1 = "New Line" End If Next Counter End sub Sub NumberOfRowsToCopy ActiveSheet.Range("$A$12:$T$1001").AutoFilter Field:=16, Criteria1:= _ "New" ActiveSheet.Range("B15:N" & NewOrderLineCounter).SpecialCells(xlCellTypeVisible).Select End sub 

(顺便说一句,我知道有可能是“更好”的方式来获取需要复制的行数(从而消除需要之间传递值),但我想我已经尝试了所有这些都没有工作。我认为它的Excel表格的格式,但这是另一个问题,你得与你给的东西工作,对不对?)

我不知道为什么你觉得一个function不适合在这里。

他们是相同的一个子,他们只是有一个返回值。

 Private Sub MainMacro() Dim lReturn As Long 'Get the return from the CommentSub lReturn = CommentSub 'Pass that to the nextsub NumberOfRowsToCopy (lReturn) End Sub Function CommentSub() As Long 'Declare the return type after the function Dim NewOrderLineCounter As Long Dim Counter As Integer For Counter = 1 To 500 If Cells(Counter, "S") = "New" Then NewOrderLineCounter = NewOrderLineCounter + 1 Cells(Counter, "V").Select ActiveCell.FormulaR1C1 = "New Line" End If Next Counter 'Here you set the return value of the funtion CommentSub = NewOrderLineCounter End Function Sub NumberOfRowsToCopy(lCount As Long) 'Declare the variable being passed to the sub. Dim NewOrderLineCounter As Long NewOrderLineCounter = lCount ActiveSheet.Range("$A$12:$T$1001").AutoFilter Field:=16, Criteria1:= _ "New" ActiveSheet.Range("B15:N" & NewOrderLineCounter).SpecialCells(xlCellTypeVisible).Select End Sub 

或者,如果您想要使用公共variables路由,请在表单或模块代码的顶部声明它们。 高于所有的function和潜艇。

 'Declared like this it can be accessed by any sub or function in this module or form. Private NewOrderLineCounter as Long 'Declared like this it can be accessed by any sub or function in this module or form and from others. Although I think if it is in a form it will not be accessible from modules. For that you can create a module called globals and declare it there as public. Public NewOrderLineCounter as Long Sub MainMacro () Call CommentSub Call NumberOfRowsToCopy End sub Sub CommentSub Dim Counter As Integer For Counter = 1 to 500 If Cells(Counter, "S") = "New" Then NewOrderLineCounter = NewOrderLineCounter + 1 Cells(Counter, "V").Select ActiveCell.FormulaR1C1 = "New Line" End If Next Counter End sub Sub NumberOfRowsToCopy ActiveSheet.Range("$A$12:$T$1001").AutoFilter Field:=16, Criteria1:= _ "New" ActiveSheet.Range("B15:N" & NewOrderLineCounter).SpecialCells(xlCellTypeVisible).Select End sub 

如果你真的坚持保持原样,就把这个值保存在这样的表格中

 Sub CommentSub Dim Counter As Integer For Counter = 1 to 500 If Cells(Counter, "S") = "New" Then NewOrderLineCounter = NewOrderLineCounter + 1 Cells(Counter, "V").Select ActiveCell.FormulaR1C1 = "New Line" End If Next Counter ws.Cells(i,j).Value = Counter End sub 

ws是你要保留的工作表,而ij是单元格的行和列的值,然后就像这样,并在之后清除它(或不)

 Sub NumberOfRowsToCopy myCounter = ws.Cells(i,j).Value ws.Cells(i,j).clear ActiveSheet.Range("$A$12:$T$1001").AutoFilter Field:=16, Criteria1:= _ "New" ActiveSheet.Range("B15:N" & NewOrderLineCounter).SpecialCells(xlCellTypeVisible).Select End sub 

但是我又觉得没有一个真正的理由不使用函数

如何传递和更新variables之间的Subs(和函数)

 Option Explicit Public Sub MainSub() Dim local_1 As Long Dim local_2 As Long local_1 = 0 local_2 = 0 setVal local_1 'Sub setVal() updates local_1 MsgBox local_1 'result: 1 putVal local_1 'Sub putVal() doesn't update local_1 MsgBox local_1 'result: 1 local_2 = getVal(local_1) 'Function getVal() updates local_1 and local_2 MsgBox local_1 'result: 2 MsgBox local_2 'result: 3 End Sub Public Sub setVal(ByRef val As Long) 'pass ByRef (not a copy) val = val + 1 End Sub Public Sub putVal(ByVal val As Long) 'pass ByVal (a copy) val = val + 1 End Sub Public Function getVal(ByRef val As Long) As Long val = val + 1 'updates val getVal = val + 1 'doesn't update val (returns a new value) End Function . 

我会用自动filterreplaceCommentSub()Sub中的For循环:

 Public Sub MainMacro() Dim newOrderRows As Long Call CommentSub(newOrderRows) Call NumberOfRowsToCopy(newOrderRows) End Sub Public Sub CommentSub(ByRef newOrderRows As Long) Dim vRng As Range With ActiveSheet.UsedRange .AutoFilter Field:=19, Criteria1:="New" Set vRng = .Offset(1, 0).Resize(.Rows.Count - 1, .Columns.Count).Columns("V") vRng.SpecialCells(xlCellTypeVisible) = "New Line" newOrderRows = vRng.SpecialCells(xlCellTypeVisible).Count .AutoFilter End With End Sub Public Function NumberOfRowsToCopy(ByVal newOrderRows As Long) As Long Dim x As Long With ActiveSheet .Range("A12:T" & .UsedRange.Rows.Count).AutoFilter Field:=16, Criteria1:="New" x = .Range("N15:N" & 15 + newOrderRows).SpecialCells(xlCellTypeVisible).Count End With NumberOfRowsToCopy = x End Function