提问人:KiwiTomTS 提问时间:11/10/2023 最后编辑:tallerKiwiTomTS 更新时间:11/10/2023 访问量:36
移动天平时 VBA 循环卡住
VBA Loop Stuck when moving balances
问:
我正在开发一个宏,该宏贯穿工作簿中的每个工作表,不包括名为“摘要”的页面,并将期末余额移动到以前的余额。它应该检查定义单元格“Statement_Name”旁边的单元格中的值。根据该值,它要么移动余额,要么移动到下一张纸。
2 个问题,宏并不总是识别“statement_Name”右侧单元格中的内容,并且并不总是移动到下一张工作表。我的直觉是,这与每个工作表中定义的单元格具有相同的名称有关,但可能是错误的。
任何帮助都非常感谢。
Sub PRIORTONEWBALANCE3()
Static FrequencyEntered As Boolean
Dim Frequency As String
Dim Statement_Name As String
If Not FrequencyEntered Then
Frequency = InputBox("Accounting cycle Q or SQ?", "Frequency") ' Ask the user for the frequency (semi or quarterly)
FrequencyEntered = True
End If
Select Case ActiveSheet.Name
Case "Summary" ' Code to execute if the sheet is named "Summary"
Sheets(ActiveSheet.Index + 1).Activate 'Move to next sheet
Case Else ' Code to execute if the sheet is not any of the specified names
ActiveSheet.Range("Statement_Name").Offset(0, 1).Select
If UCase(Frequency) = "Q" And InStr(1, ActiveCell.Value, "Semi-Annual") Then
Sheets(ActiveSheet.Index + 1).Activate 'Move to next sheet
Else
ActiveSheet.Range("Ending_Balance").Select
Selection.Copy
ActiveSheet.Range("Prior_Balance").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False 'Paste to ending balance
Selection.NumberFormat = "_($* #,##0.00_);_($* (#,##0.00);_($* ""-""??_);_(@_)"
Application.CutCopyMode = False 'Clear Clipboard
Sheets(ActiveSheet.Index + 1).Activate 'Move to next sheet
End If
End Select
End Sub
尝试了循环而不是选择案例。
答:
- 循环访问除 之外的所有工作表。
Summary
- 如果工作表满足特定条件,请将值从 复制到 。
Ending_Balance
Prior_Balance
标准取决于用户输入
如果用户输入为“Q”,请检查关键字单元格(名为“Statement_Name”的单元格旁边的单元格)是否包含单词“Quarter”。
如果用户输入为“SQ”,请检查关键字单元格是否包含单词“Semi-Annual”。
注意:您可能需要根据需要修改条件。
Sub PRIORTONEWBALANCE3()
Static FrequencyEntered As Boolean
Dim Frequency As String, sFreq As String
Dim Statement_Name As String
Dim Sht As Worksheet
If Not FrequencyEntered Then
Frequency = InputBox("Accounting cycle Q or SQ?", "Frequency")
FrequencyEntered = True
End If
For Each Sht In ThisWorkbook.Worksheets
If Sht.Name <> "Summary" Then
On Error Resume Next
sFreq = Sht.Range("Statement_Name").Offset(0, 1).Value
On Error GoTo 0
If (Frequency = "Q" And InStr(1, sFreq, "Quarter", vbTextCompare) > 0) Or _
(Frequency = "SQ" And InStr(1, sFreq, "Semi-Annual", vbTextCompare) > 0) Then
With Sht.Range("Prior_Balance")
.Value = Sht.Range("Ending_Balance").Value
.NumberFormat = "_($* #,##0.00_);_($* (#,##0.00);_($* ""-""??_);_(@_)"
End With
End If
End If
Next
End Sub
总结:
- 您的代码不会遍历您的工作表
- 您的代码不会对Statement_Name单元格旁边的单元格执行任何操作
- 可以在不同的工作表上使用具有相同名称的多个命名范围
- 使用 和 可能会出现意外错误,因此请直接引用您的单元格和工作表
ActiveSheet
Select
它并不总是移动到下一张纸
您的代码没有任何内容可以将其移动到下一个工作表。这将使新工作表可见,但您的代码不会在每个工作表中移动。如果你想遍历一堆工作表,你需要某种循环结构。可能是一个 For Each 循环。例如,下面的代码循环遍历工作簿中的所有工作表,如果它们未命名为“Sheet1”,则打印它们的名称。.Activate
Private Sub ForEachDemo()
Dim wkSheet As Worksheet
For Each wkSheet In ThisWorkbook.Sheets
If wkSheet.Name <> "Sheet1" Then
Debug.Print wkSheet.Name
End If
Next wkSheet
End Sub
宏并不总是识别“statement_Name”右侧单元格中的内容
代码在选择单元格后不会对单元格执行任何操作。
看到你的线路了吗?之后会发生什么?输入语句。
在语句 () 的第一个分支上,代码所做的只是激活一个新工作表。
在语句的第二个分支上,代码现在选择另一个单元格。无论哪种方式,都不会对您选择的第一个单元格执行任何操作。ActiveSheet.Range("Statement_Name").Offset(0, 1).Select
If
If
If UCase(Frequency) = "Q" And InStr(1, ActiveCell.Value, "Semi-Annual") Then
If
我的直觉是,这与每个工作表中定义的单元格具有相同的名称有关,但可能是错误的。
这是很好的直觉,但我不认为这会导致你的问题。或者,至少不是直接的。在不同的工作表上对不同的范围使用相同的名称是没有问题的。毕竟,我们在每张纸上都有一个名为“A1”的单元格!您只需要确保在每张纸上选择正确的范围即可。这就是您使用 的原因,但是当我们遍历所有工作表时,我们可以使其更加健壮。这只是用户目前可以与之交互的任何工作表。VBA 不必像人一样“看到”工作表即可与之交互,因此我们将通过直接引用工作表来绕过这一点。ActiveSheet
ActiveSheet
考虑到这些想法,我们可以重写部分代码以执行您想要的操作。
Private Sub Rewrite()
Static FrequencyEntered As Boolean
Dim Frequency As String
' Ask the user for the frequency (semi or quarterly)
If Not FrequencyEntered Then
Frequency = InputBox("Accounting cycle Q or SQ?", "Frequency")
FrequencyEntered = True
End If
' You need to assign some value to Statement_Name, or this code will error out
Dim Statement_Name As String
' Loop through all worksheets in this workbook
Dim wksheet As Worksheet
For Each wksheet In ThisWorkbook.Sheets
' Ignore the sheet named "Summary"
If wksheet.Name <> "Summary" Then
' Ignore the sheet if "Q" frequency was selected
If UCase(Frequency) <> "Q" Then
wksheet.Range("Statement_Name").Offset(0, 1).Select
' Ignore the sheet if "Semi-Annual" is in the selected cell
If InStr(1, ActiveCell.Value, "Semi-Annual") = 0 Then
' Get the value of the ending balance
Dim endingBalance As Double
endingBalance = wksheet.Range("Ending_Balance").Value
' Put the ending balance value in the prior balance cell
wksheet.Range("Prior_Balance").Value = endingBalance
' Change the number format of the prior balance cell
wksheet.Range("Prior_Balance").NumberFormat = "_($* #,##0.00_);_($* (#,##0.00);_($* ""-""??_);_(@_)"
End If
End If
End If
Next wksheet
End Sub
与任何问题一样,不可能说这是否能解决由代码中未显示的其他部分引起的问题。但我相信你的直接问题和问题在这里得到了解决。
评论