移动天平时 VBA 循环卡住

VBA Loop Stuck when moving balances

提问人:KiwiTomTS 提问时间:11/10/2023 最后编辑:tallerKiwiTomTS 更新时间:11/10/2023 访问量:36

问:

我正在开发一个宏,该宏贯穿工作簿中的每个工作表,不包括名为“摘要”的页面,并将期末余额移动到以前的余额。它应该检查定义单元格“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

尝试了循环而不是选择案例。

Excel VBA 循环

评论


答:

0赞 taller 11/10/2023 #1
  • 循环访问除 之外的所有工作表。Summary
  • 如果工作表满足特定条件,请将值从 复制到 。Ending_BalancePrior_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

1赞 TehDrunkSailor 11/10/2023 #2

总结:

  • 您的代码不会遍历您的工作表
  • 您的代码不会对Statement_Name单元格旁边的单元格执行任何操作
  • 可以在不同的工作表上使用具有相同名称的多个命名范围
  • 使用 和 可能会出现意外错误,因此请直接引用您的单元格和工作表ActiveSheetSelect

它并不总是移动到下一张纸

您的代码没有任何内容可以将其移动到下一个工作表。这将使新工作表可见,但您的代码不会在每个工作表中移动。如果你想遍历一堆工作表,你需要某种循环结构。可能是一个 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).SelectIfIfIf UCase(Frequency) = "Q" And InStr(1, ActiveCell.Value, "Semi-Annual") ThenIf

我的直觉是,这与每个工作表中定义的单元格具有相同的名称有关,但可能是错误的。

这是很好的直觉,但我不认为这会导致你的问题。或者,至少不是直接的。在不同的工作表上对不同的范围使用相同的名称是没有问题的。毕竟,我们在每张纸上都有一个名为“A1”的单元格!您只需要确保在每张纸上选择正确的范围即可。这就是您使用 的原因,但是当我们遍历所有工作表时,我们可以使其更加健壮。这只是用户目前可以与之交互的任何工作表。VBA 不必像人一样“看到”工作表即可与之交互,因此我们将通过直接引用工作表来绕过这一点。ActiveSheetActiveSheet

考虑到这些想法,我们可以重写部分代码以执行您想要的操作。

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

与任何问题一样,不可能说这是否能解决由代码中未显示的其他部分引起的问题。但我相信你的直接问题和问题在这里得到了解决。