[英]Run a VBA macro to trigger macros in different sheets
The situation is like this: I have 40 worksheets embedded with same Macros called RetrieveNumbers . 情况是这样的:我有40个工作表,其中嵌入了称为RetrieveNumbers的相同宏 。 The end results in 40 sheets will be different based upon various parameters in each worksheet.
40张纸的最终结果将因每个工作表中的各种参数而有所不同。
To update the numbers, I manually click the macro buttons to retrieve numbers in the 40 worksheets. 要更新数字,我手动单击宏按钮以检索40个工作表中的数字。 As a result of that, I'm sick of it.
结果,我对此感到厌烦。 To simplify the testing, I only use two sheets(Sheet1, Sheet2) to test if, by clicking a Macro named RunAll, it would run through the two Macros.
为了简化测试,我仅使用两个工作表(Sheet1,Sheet2)来测试是否通过单击名为RunAll的宏来运行两个宏。
Surely, I have FAILED. 当然,我失败了。
I have tried : 我努力了 :
application.run 应用程序运行
call 呼叫
Two scenarios I tried: 我尝试了两种情况:
I hit F5 as I was in the RunAll window and my other screen on the Sheet1 worksheet . 我就像在RunAll窗口中以及在Sheet1工作表上的其他屏幕中一样,按了 F5。 It runs perfectly and yet it runs twice in Sheet1 rather than going to Sheet2.
它运行完美,但是在Sheet1中运行了两次,而不是进入Sheet2。
I hit F5 as I was in the RunAll window and my another screen on the RunAll worksheet . 我在RunAll窗口中看到了F5, 在RunAll工作表中又看到了另一个屏幕。 After clicking it, I went back to see if there were any numbers.
单击它之后,我返回查看是否有数字。 And surely, there weren't.
当然,没有。
I thought the Macro would go to Sheet2 and then run Macro Retrivenumbers2. 我以为宏会转到Sheet2,然后运行Macro Retrivenumbers2。 But it didn't.
但事实并非如此。 It stayed at the current worksheet.
它停留在当前的工作表上。 Please give me some guidance on how to run the next sheets I want.
请给我一些有关如何运行我想要的下一张纸的指导。 Let me know if I need to clarify more on this question.
让我知道是否需要进一步澄清这个问题。
The Macro RetrieveNumbers 宏检索编号
(Since the Macro RetrieveNumbers2 is as same as RetrieveNumbers1, I don't include it) (由于宏RetrieveNumbers2与RetrieveNumbers1相同,因此我不包含它)
Sub RetrieveNumbers1()
Dim NumberFiles As Integer, FilesVisited As Integer, RowNumber As Integer
Let NumberFiles = ActiveSheet.Cells("2", "A").Value
Let FilesVisited = 0 'start from 0
Let RowNumber = 4 'start from column B
If NumberFiles > 30 Then
MsgBox "Don't try to retrieve numbers from more than 30 files at a time!"
Else
For FilesVisited = 1 To NumberFiles
'Open files, get path, file, tab name and cells
Dim PathFileOpen As String, NameFileOpen As String, NameTab As String, FileDir As String
Let PathFileOpen = ActiveSheet.Cells(RowNumber, "A").Text
Let NameFileOpen = ActiveSheet.Cells(RowNumber, "B").Text
Let NameTab = ActiveSheet.Cells(RowNumber, "C").Text
Dim N As Integer, Cell As String, NumberYears As String, FullLink As String
NumberYears = ActiveSheet.Cells("2", "B").Value
For N = 4 To NumberYears + 3
Cell = ActiveSheet.Cells(RowNumber, N).Text
FullLink = "(=)'" & PathFileOpen & "\[" & NameFileOpen & ".xlsm]" & NameTab & "'!" & Cell
ActiveSheet.Cells(RowNumber, N + 13).Value = FullLink
Next N
RowNumber = RowNumber + 1
Next FilesVisited
End If
ActiveSheet.Range("A1").CurrentRegion.Replace What:="(=)", Replacement:="=", _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False,
SearchFormat:=False, ReplaceFormat:=False
End Sub
The Macro RunAll 宏RunAll
Sub runall()
Call Sheet1.RetrieveNumbers1
Call Sheet2.RetrieveNumbers2
End Sub
Clear Example of the file Working file example 清除 文件示例工作文件示例
There's a fair amount wrong with your code. 您的代码有很多错误。 As @PGCodeRider said in his answer - have one procedure that runs on all sheets.
正如@PGCodeRider在回答中所说的-在所有工作表上运行一个过程。 His code has the loop within the procedure.
他的代码在过程中具有循环。
This code uses a separate procedure to cycle through the sheets and passes a reference to the sheet to the RetrieveNumbers
procedure. 该代码使用一个单独的过程来循环工作表,并将对工作表的引用传递给
RetrieveNumbers
过程。
I've replaced all instances of ActiveSheet
(reference to the ActiveSheet) with wrkSht
(reference to the sheet that the RunAllSheets
procedure passes). 我已用
wrkSht
(对RunAllSheets
过程通过的工作表的引用)替换了ActiveSheet
所有实例(对ActiveSheet的引用)。
All Dims
have been moved to the top of the code as they only need declaring once and not on each loop (you change the value the variables hold on each loop, but no need to declare them again). 所有
Dims
已移至代码顶部,因为它们只需要声明一次,而不是在每个循环中声明(您可以更改变量在每个循环中保留的值,而无需再次声明它们)。
Sub RunOnAllSheets()
Dim wrkSht As Worksheet
For Each wrkSht In ThisWorkbook.Worksheets
Select Case wrkSht.Name
Case "Sheet1", "Sheet2"
'Do nothing.
Case Else
'For all other sheets execute the RetrieveNumbers procedure
'and pass the wrkSht variable to it.
RetrieveNumbers wrkSht
End Select
Next wrkSht
End Sub
Sub RetrieveNumbers(wrkSht As Worksheet)
Dim NumberFiles As Integer, FilesVisited As Integer, RowNumber As Integer
'You only need to declare these once.
Dim PathFileOpen As String, NameFileOpen As String, NameTab As String, FileDir As String
Dim N As Integer, Cell As String, NumberYears As String, FullLink As String
'No need to use 'LET' it's a left-over from the days of Sinclair Basic
'ok, maybe not.... but it's an old way of doing it.
NumberFiles = wrkSht.Cells("2", "A").Value
FilesVisited = 0 'start from 0
RowNumber = 4 'start from column B
If NumberFiles > 30 Then
MsgBox "Don't try to retrieve numbers from more than 30 files at a time!"
Else
For FilesVisited = 1 To NumberFiles
'Open files, get path, file, tab name and cells
PathFileOpen = wrkSht.Cells(RowNumber, "A").Text
NameFileOpen = wrkSht.Cells(RowNumber, "B").Text
NameTab = wrkSht.Cells(RowNumber, "C").Text
NumberYears = wrkSht.Cells("2", "B").Value
For N = 4 To NumberYears + 3
Cell = wrkSht.Cells(RowNumber, N).Text
FullLink = "(=)'" & PathFileOpen & "\[" & NameFileOpen & ".xlsm]" & NameTab & "'!" & Cell
wrkSht.Cells(RowNumber, N + 13).Value = FullLink
Next N
RowNumber = RowNumber + 1
Next FilesVisited
End If
wrkSht.Range("A1").CurrentRegion.Replace What:="(=)", Replacement:="=", _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
End Sub
Edit, after accepted as answer: 接受答案后进行编辑:
This method only references the sheet twice. 此方法仅引用工作表两次。 Once to pull the link info, and once more to put the final formula back on the sheet.
一次提取链接信息,再一次将最终公式放回工作表。
Sub RunOnAllSheets()
Dim wrkSht As Worksheet
For Each wrkSht In ThisWorkbook.Worksheets
'Have removed the Select Case statement so it looks at all sheets.
RetrieveNumbers wrkSht
Next wrkSht
End Sub
Sub RetrieveNumbers(wrkSht As Worksheet)
Dim NumberFiles As Long, FilesVisited As Long
Dim vCellValues As Variant, vLinkValues() As Variant
Dim FullPath As String
Dim x As Long
With wrkSht
'Get the last row number that contains data in column N.
NumberFiles = .Cells(.Rows.Count, "N").End(xlUp).Row
If NumberFiles - 3 > 30 Then
MsgBox "Don't try to retrieve numbers from more than 30 files at a time!"
Else
'Pass the cell values to an array.
vCellValues = .Range("A4:C4")
'Create the full path excluding the cell reference.
FullPath = "='" & vCellValues(1, 1) & "[" & vCellValues(1, 2) & "]" & vCellValues(1, 3) & "'!"
'Create an array of full path & cell references.
ReDim vLinkValues(1 To NumberFiles - 3) 'Set the array size.
For x = 1 To NumberFiles - 3
vLinkValues(x) = FullPath & .Cells(x + 3, "N")
Next x
'Paste the array back to the sheet.
.Range(.Cells(4, "N"), .Cells(NumberFiles, "N")).Formula = vLinkValues
End If
End With
End Sub
Note: This assumes your path is just in cell A4:C4, as indicated by the code vCellValues = .Range("A4:C4")
(I'm not sure this is the case now). 注意:这假定您的路径仅在单元格A4:C4中,如代码
vCellValues = .Range("A4:C4")
(我现在不确定是这种情况)。
If your paths are on each row matching the cell values you'll need to: 如果您的路径在与单元格值匹配的每一行上,则需要:
vCellValues = .Range("A4:C4")
to vCellValues = .Range("A4:C4")
更改为 vCellValues = .Range(.Cells(4, 1), .Cells(NumberFiles, 3))
FullPath='....
line. FullPath='....
行。 vLinkValues(x) = FullPath & .Cells(x + 3, "N")
to vLinkValues(x) = FullPath & .Cells(x + 3, "N")
更改为 vLinkValues(x) = "='" & vCellValues(x, 1) & "[" & vCellValues(x, 2) & "]" & vCellValues(x, 3) & "'!" & .Cells(x + 3, "N")
Try running a loop through all of the sheets in the workbook? 尝试遍历工作簿中的所有工作表吗? Also make sure you run this in a module in your vba editor.
还要确保在vba编辑器的模块中运行此命令。 Not your sheet code.
不是您的工作表代码。
Sub RetrieveNumbers1()
Dim WS As Worksheet
'loop that goes through all sheets in your workbook. Where you used to have
'activesheet, I changed to ws
For Each WS In ThisWorkbook.Sheets
Dim NumberFiles As Integer, FilesVisited As Integer, RowNumber As Integer
Let NumberFiles = WS.Cells("2", "A").Value
Let FilesVisited = 0 'start from 0
Let RowNumber = 4 'start from column B
If NumberFiles > 30 Then
MsgBox "Don't try to retrieve numbers from more than 30 files at a time!"
Else
For FilesVisited = 1 To NumberFiles
'Open files, get path, file, tab name and cells
Dim PathFileOpen As String, NameFileOpen As String, NameTab As String, FileDir As String
Let PathFileOpen = WS.Cells(RowNumber, "A").Text
Let NameFileOpen = WS.Cells(RowNumber, "B").Text
Let NameTab = WS.Cells(RowNumber, "C").Text
Dim N As Integer, Cell As String, NumberYears As String, FullLink As String
NumberYears = WS.Cells("2", "B").Value
For N = 4 To NumberYears + 3
Cell = WS.Cells(RowNumber, N).Text
FullLink = "(=)'" & PathFileOpen & "\[" & NameFileOpen & ".xlsm]" & NameTab & "'!" & Cell
WS.Cells(RowNumber, N + 13).Value = FullLink
Next N
RowNumber = RowNumber + 1
Next FilesVisited
End If
ws.Range("A1").CurrentRegion.Replace What:="(=)", Replacement:="=", _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False,
SearchFormat:=False, ReplaceFormat:=False
'restarts on the next ws
Next WS
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.