【问题标题】:VBA passing string variable to subVBA将字符串变量传递给子
【发布时间】:2021-04-16 20:52:08
【问题描述】:

我正在修改我当前的代码,使其更加用户友好。我的原始代码有硬编码的文件路径。下面的新代码从“控件”子传递文件路径,它们由输入框指定。我遇到的问题是,现在,一旦在私有子例程中,If 语句不再起作用。唯一的区别是文件路径是从另一个 sub 传递的,而不是硬编码到这个 sub 中。我不确定我错过了什么。任何帮助都会很棒。

Private Sub copyGLbuildings(NewRecPath As String, GLsrcPath As String)

Dim fname1 As Variant
Dim fname2 As Variant


Dim wb1 As Workbook
Dim Wb0 As Workbook


fname1 = Dir(GLsrcPath & "*Buildings*")
fname2 = Dir(NewRecPath & "*Buildings Rec*")

If fname1 <> "" Then
    Set wb1 = Workbooks.Open(GLsrcPath & fname1)
End If

If fname2 <> "" Then
    Set Wb0 = Workbooks.Open(NewRecPath & fname2)
End If

    Wb0.Sheets(1).Name = "Data"
    Wb0.Sheets.Add.Name = "GL"
    wb1.Worksheets(1).UsedRange.Copy
    Wb0.Worksheets("GL").UsedRange.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Wb0.Worksheets("GL").UsedRange.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Wb0.Worksheets("GL").UsedRange.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
      

    Wb0.Worksheets(1).Activate
    ActiveWorkbook.Windows(1).DisplayGridlines = False
 
 Call CleanFAGL
 
    wb1.Close
    Wb0.Close savechanges:=True
        

End Sub

【问题讨论】:

  • NewRecPath 的末尾是否有反斜杠? GLsrcPath呢?
  • 在'if fname1'之前在你的代码中放置一个断点,并在locals窗口中查看fname1和fname2的值。这些值是正确格式的文件路径吗?
  • @braX - 不,他们没有。我想当有人从文件资源管理器复制时,不包括结尾斜杠;至少在我测试的时候还没有。
  • @freeflow - 作为编码新手,我不知道您可以像这样进入代码。一旦我这样做了,很明显 fname1 和 fname 2 没有任何价值。我在指定变体时缺少反斜杠。现在看起来效果很好!

标签: excel vba subroutine


【解决方案1】:

代码对我来说看起来不错。我建议您在第一个 If 语句上设置一个断点,并使用 View > Locals 检查 NewRecPath 和 GLsrcPath 的值是作为什么传递到子例程的。

【讨论】:

    【解决方案2】:

    复制到另一个工作簿

    • 在Source(读取)之前使用Destination(写入)作为参数是很不寻常的。
    • fname 最好写成fName。
    • fNames 都不会是“”,因为您之前已经添加了模式。
    • wb0 是一个可怕的想法,至少本着Excel 和VBA 的精神,从1 开始编号。请注意,我选择的变量名也不是很好,但只有您完全了解它的含义,才能改进它。
    • 如果是工作表,则称其为工作表(可读性)或至少保持一致。
    • 在添加不带参数的工作表后,它将“降落”在选定(活动)工作表之前,因此如果工作簿中只有一个工作表,它将是第一个工作表。如果不是,如果你能明确解决这个问题,你为什么要赌它?
    • 考虑一下PasteSpecial 行的顺序,例如您在复制数据之前调整了列宽。
    • 使用工作表或工作表索引容易出错和混淆,在这种情况下,我不知道应该“剥夺”哪个工作表显示网格线。
    • 其余的都包含在您的 cmets 中。
    • 别担心,我们都曾在这一点上。
    • 仔细阅读 cmets 并适当修改代码。
    Option Explicit
    
    ' Note that the arguments are switched due to the 'From To' logic.
    Private Sub copyGLbuildings( _
            ByVal SourcePath As String, _
            ByVal DestinationPath As String)
        
        ' Validate
        
        ' Destination
        Dim dwbName As String: dwbName = Dir(DestinationPath & "*Buildings Rec*")
        If dwbName = "" Then Exit Sub
        
        ' Source
        Dim swbName As String: swbName = Dir(SourcePath & "*Buildings*")
        If swbName = "" Then Exit Sub
        
        'Application.ScreenUpdating = False
        
        ' Destination
        
        ' Workbook
        If Right(dwbName, 1) <> "\" Then
            dwbName = dwbName & "\"
        End If
        Dim dwb As Workbook: Set dwb = Workbooks.Open(DestinationPath & dwbName)
        
        ' Worksheets
        Dim dws1 As Worksheet: Set dws1 = dwb.Worksheets(1)
        dws1.Name = "Data"
        Dim dws2 As Worksheet
        ' Do it explicitly, even if there is previously only one worksheet.
        Set dws2 = dwb.Worksheets.Add(After:=dws1) ' ??? maybe Before:=dws1
        dws2.Name = "GL"
        
        ' Source
        
        If Right(swbName, 1) <> "\" Then
            swbName = swbName & "\"
        End If
        Dim swb As Workbook: Set swb = Workbooks.Open(SourcePath & swbName)
        ' Copy
        swb.Worksheets(1).UsedRange.Copy
        
        ' Destination
        
        ' Paste
        With dws2.UsedRange
            .PasteSpecial Paste:=xlPasteFormats
            .PasteSpecial Paste:=xlPasteValues
            .PasteSpecial Paste:=xlPasteColumnWidths
        End With
        Application.CutCopyMode = False
        ' Dispay Gridlines
        dws1.Activate ' ??? if "Data" or dws2.Activate ' if "GL": depending on After
        dwb1.Windows(1).DisplayGridlines = False
         
        CleanFAGL ' ??? Not knowing what this does, doesn't help.
         
        Application.DisplayAlerts = False
        swb.Close SaveChanges:=False
        dwb.Close SaveChanges:=True
        Application.DisplayAlerts = True
    
        'Application.ScreenUpdating = True
    
    End Sub
    

    【讨论】:

    • 非常感谢您指出细节并为我展示精心组织的代码集的外观。由于对编码如此陌生,我基本上已经从各地获得了我的方向,我的最终产品往往是各种代码的科学怪人,并根据我自己在博客和演练上的阅读进行了调整。所以,再次感谢您。
    猜你喜欢
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    • 2017-11-15
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多