【问题标题】:Hitting a snag with a Sub and multiple Functions. Attempting to make it a one button push action使用 Sub 和多个函数遇到障碍。试图使其成为一键式按钮操作
【发布时间】:2012-06-01 13:54:35
【问题描述】:

代码已更新,我收到错误消息,即使在检查 Microsoft Scripting RunTime 以使其处于活动状态后也是如此。以下是错误:

Option Explicit

Sub Update_JL()

    Dim wsJL As Worksheet 'Jobs List
    Dim wsJD As Worksheet 'Jobs Data
    Dim wsJAR As Worksheet 'JL Archive
    Dim lastrow As Long, fstcell As Long
    Dim strCompany As String, strPart As String, strPath As String

    Set wsJL = Sheets("Jobs List")
    Set wsJD = Sheets("Jobs Data")
    Set wsJAR = Sheets("JL Archive")

    With Application
        .ScreenUpdating = False
        .DisplayAlerts = False
        .EnableEvents = False
    End With

    With Intersect(wsJL.UsedRange, wsJL.Columns("Q"))
        .AutoFilter 1, "<>Same"
        With Intersect(.Offset(2).EntireRow, .Parent.Range("B:O"))
            .Copy wsJAR.Cells(Rows.Count, "B").End(xlUp).Offset(1)
            .EntireRow.Delete
        End With
        .AutoFilter
    End With

    With wsJD
        'Clean empty cells in Column C
        lastrow = Range("B" & Rows.Count).End(xlUp).Row + 1
        Range("C5:C" & lastrow).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
    End With

    With Intersect(wsJD.UsedRange, wsJD.Columns("Q"))
        ActiveSheet.Range("P:Q").Calculate
        .AutoFilter 1, "<>Different"
        .SpecialCells(xlCellTypeVisible).EntireRow.Delete
    End With

    With wsJD
        .AutoFilterMode = False
        Intersect(.UsedRange, .Columns("G")).Cut .Range("F1")
        Intersect(.UsedRange, .Columns("H")).Cut .Range("G1")
        Intersect(.UsedRange, .Columns("L")).Cut .Range("H1")
        Intersect(.UsedRange, .Columns("N")).Cut .Range("I1")
        Intersect(.UsedRange, .Range("B:I")).Copy wsJL.Cells(Rows.Count, "B").End(xlUp).Offset(1)
    End With

        With wsJL
        lastrow = wsJL.Cells(Rows.Count, "B").End(xlUp).Row
        wsJL.Range("R1:Y1").Copy
        wsJL.Range("B3:I" & lastrow).PasteSpecial xlPasteFormats
        lastrow = wsJL.Cells(Rows.Count, "J").End(xlUp).Row + 1
        fstcell = wsJL.Cells(Rows.Count, "I").End(xlUp).Row
        wsJL.Range("Z1:AG1").Copy wsJL.Range("J" & fstcell & ":Q" & lastrow)
        wsJL.Range("S2:X2").Copy wsJL.Range("P" & fstcell & ":T" & lastrow)
        lastrow = wsJL.Cells(Rows.Count, "B").End(xlUp).Row
        wsJL.Range("J:Q").Calculate
        Range("B3:N" & lastrow).Sort key1:=Range("F3" & lastrow), order1:=xlAscending

    End With

    With wsJAR
        lastrow = wsJAR.Cells(Rows.Count, "O").End(xlUp).Row
        wsJAR.Range("R2:T2").Copy wsJAR.Range("R3:T" & lastrow)
        wsJAR.Range("M1").Copy wsJAR.Range("M3:M" & lastrow)
    End With

    With wsJL
        strCompany = Range("C3") ' assumes company name in C3
        strPart = CleanName(Range("D3")) ' assumes part in D1
        strPath = CleanName(Range("Lists!$G$2"))

        If Not FolderExists(strPath & strCompany) Then
        'company doesn't exist, so create full path
            FolderCreate strPath & strCompany & Application.PathSeparator & strPart
        Else
        'company does exist, but does part folder
            If Not FolderExists(strPath & strCompany & Application.PathSeparator & strPart) Then
                FolderCreate strPath & strCompany & Application.PathSeparator & strPart
            End If
        End If

        Range("J:M").Calculate
    End With

    With Application
        .ScreenUpdating = True
        .DisplayAlerts = True
        .EnableEvents = True
    End With

End Sub

Function FolderCreate(ByVal path As String) As Boolean

FolderCreate = True
Dim fso As New FileSystemObject

If Functions.FolderExists(path) Then
    Exit Function
Else
    On Error GoTo DeadInTheWater
    fso.CreateFolder path ' could there be any error with this, like if the path is really screwed up?
    Exit Function
End If

DeadInTheWater:
    MsgBox "A folder could not be created for the following path: " & path & ". Check the path name and try again."
    FolderCreate = False
    Exit Function

End Function

Function FolderExists(ByVal path As String) As Boolean

FolderExists = False
Dim fso As New FileSystemObject

If fso.FolderExists(path) Then FolderExists = True

End Function

Function CleanName(strName As String) As String
'will clean part # name so it can be made into valid folder name
'may need to add more lines to get rid of other characters

    CleanName = Replace(strName, "/", "")
    CleanName = Replace(CleanName, "*", "")
    CleanName = Replace(CleanName, ".", "")

End Function

到目前为止,错误就在这里,因为这是脚本允许我去的地方。错误是:

Compile Error: Variable not defined

代码如下,争用的地方在*之间。 If **Functions**.FolderExists(path) Then

Function FolderCreate(ByVal path As String) As Boolean

FolderCreate = True
Dim fso As New FileSystemObject

If Functions.FolderExists(path) Then
    Exit Function
Else
    On Error GoTo DeadInTheWater
    fso.CreateFolder path ' could there be any error with this, like if the path is really screwed up?
    Exit Function
End If

DeadInTheWater:
    MsgBox "A folder could not be created for the following path: " & path & ". Check the path name and try again."
    FolderCreate = False
    Exit Function

End Function

【问题讨论】:

  • 为什么需要一个子?将内容分成多个部分有助于提高可读性。如果 subs 或函数需要一个接一个地调用,那么设置一个 main 例程来调用它们
  • 原因是因为这需要一个按钮推送的概念。这就是为什么。我无法调整它以使其成为多按钮选项。
  • 您不需要多个按钮。 Sean 的建议是创建一个除了调用其他子程序之外什么都不做的主程序。您的按钮将调用主程序。
  • 以这个答案中的代码为例:stackoverflow.com/a/10779424/138938 DispatchTotalsByPNNumber 是一个调用其他的子。
  • 这并不是说不同。我修复了 OP 对我在下面的答案中构建的函数的原始集成,他误解了如何集成我所做的函数调用。

标签: excel vba


【解决方案1】:

你只是把代码弄错了一点。

每个新函数都应该放在 sub 之下,因为它是一个从 sub 调用的单独过程。值得一读函数和子函数并相互调用它们。

我在下面进行了重组。希望会更加清晰和干净。

Option Explicit

Sub Update_JL()

    Dim wsJL As Worksheet 'Jobs List
    Dim wsJD As Worksheet 'Jobs Data
    Dim wsJAR As Worksheet 'JL Archive
    Dim lastrow As Long, fstcell As Long
    Dim strCompany As String, strPart As String, strPath As String

    Set wsJL = Sheets("Jobs List")
    Set wsJD = Sheets("Jobs Data")
    Set wsJAR = Sheets("JL Archive")

    With Application
        .ScreenUpdating = False
        .DisplayAlerts = False
        .EnableEvents = False
    End With

    With Intersect(wsJL.UsedRange, wsJL.Columns("Q"))
        .AutoFilter 1, "<>Same"
        With Intersect(.Offset(2).EntireRow, .Parent.Range("B:O"))
            .Copy wsJAR.Cells(Rows.Count, "B").End(xlUp).Offset(1)
            .EntireRow.Delete
        End With
        .AutoFilter
    End With

    With wsJD
        'Clean up step 1
        lastrow = Range("B" & Rows.Count).End(xlUp).Row + 1
        Range("C5:C" & lastrow).SpecialCells(xlCellTypeBlanks).EntireRow.Delete

        'Blow away rows that are useless
        lastrow = Range("B5").End(xlDown).Row
        Range("P5:Q5").Copy wsJD.Range("P6:Q" & lastrow)
        wsJD.UsedRange.Copy Sheets.Add.Range("A1")
    End With

    With Intersect(ActiveSheet.UsedRange, ActiveSheet.Columns("Q"))
        ActiveSheet.Range("P:Q").Calculate
        .AutoFilter 1, "<>Different"
        .SpecialCells(xlCellTypeVisible).EntireRow.Delete
    End With

    With ActiveSheet
        ActiveSheet.Range("P:Q").Calculate
        .AutoFilterMode = False
        Intersect(.UsedRange, .Columns("G")).Cut .Range("F1")
        Intersect(.UsedRange, .Columns("H")).Cut .Range("G1")
        Intersect(.UsedRange, .Columns("L")).Cut .Range("H1")
        Intersect(.UsedRange, .Columns("N")).Cut .Range("I1")
        Intersect(.UsedRange, .Range("B:I")).Copy wsJL.Cells(Rows.Count, "B").End(xlUp).Offset(1)
        .Delete
    End With

    With wsJL
        lastrow = wsJL.Cells(Rows.Count, "B").End(xlUp).Row
        wsJL.Range("R1:Y1").Copy
        wsJL.Range("B3:I" & lastrow).PasteSpecial xlPasteFormats
        lastrow = wsJL.Cells(Rows.Count, "J").End(xlUp).Row + 1
        fstcell = wsJL.Cells(Rows.Count, "I").End(xlUp).Row
        wsJL.Range("Z1:AG1").Copy wsJL.Range("J" & fstcell & ":Q" & lastrow)
        wsJL.Range("S2:X2").Copy wsJL.Range("P" & fstcell & ":T" & lastrow)
        lastrow = wsJL.Cells(Rows.Count, "B").End(xlUp).Row
        wsJL.Range("J:Q").Calculate
        Range("B3:N" & lastrow).Sort key1:=Range("F3" & lastrow), order1:=xlAscending

    End With

    With wsJAR
        lastrow = wsJAR.Cells(Rows.Count, "O").End(xlUp).Row
        wsJAR.Range("R2:T2").Copy wsJAR.Range("R3:T" & lastrow)
        wsJAR.Range("M1").Copy wsJAR.Range("M3:M" & lastrow)
    End With

    With wsJL

        strCompany = Range("C3") ' assumes company name in C3
        strPart = CleanName(Range("D3")) ' assumes part in D1
        strPath = CleanName(Range("Lists!$G$2"))

        If Not FolderExists(strPath & strCompany) Then
        'company doesn't exist, so create full path
            FolderCreate strPath & strCompany & Application.PathSeparator & strPart
        Else
        'company does exist, but does part folder
            If Not FolderExists(strPath & strCompany & Application.PathSeparator & strPart) Then
                FolderCreate strPath & strCompany & Application.PathSeparator & strPart
            End If
        End If

        Range("J:M").Calculate

    End With


    With Application
        .ScreenUpdating = True
        .DisplayAlerts = True
        .EnableEvents = True
    End With

End Sub

Function FolderCreate(ByVal path As String) As Boolean

FolderCreate = True
Dim fso As New FileSystemObject

If FolderExists(path) Then
    Exit Function
Else
    On Error GoTo DeadInTheWater
    fso.CreateFolder path ' could there be any error with this, like if the path is really screwed up?
    Exit Function
End If

DeadInTheWater:
    MsgBox "A folder could not be created for the following path: " & path & ". Check the path name and try again."
    FolderCreate = False
    Exit Function

End Function

Function FolderExists(ByVal path As String) As Boolean

FolderExists = False
Dim fso As New FileSystemObject

If fso.FolderExists(path) Then FolderExists = True

End Function

Function CleanName(strName As String) As String
'will clean part # name so it can be made into valid folder name
'may need to add more lines to get rid of other characters

    CleanName = Replace(strName, "/", "")
    CleanName = Replace(CleanName, "*", "")
    CleanName = Replace(CleanName, ".", "")

End Function

【讨论】:

  • 代码也可以为了可读性而被清理更多,就像你知道的那样。我进行了一些清理编辑,但我留下了所有 ActiveSheet 的东西,因为我不知道 ActiveSheet 将是什么......
  • 活动工作表将是从这里创建的“新工作表”UsedRange.Copy Sheets.Add.Range("A1") 它没有名称,只是一个新工作表。所以这就是它没有名字的原因,除了 ActiveSheet。一旦我完成了我遇到的另一个问题,我会看看你所做的并输入它。在添加了我正在处理的另一个问题后,我不得不移动一些东西,而且似乎代码有效,但我倾向于遇到不应该的组织错误。再次感谢:)
  • 看看我是如何组织上述内容的,它将帮助您了解需要如何组织和保持方法和程序(例如 With -> End With 等)它应该有助于理清问题。跨度>
  • 我实际上正在检查我的旧脚本和这个脚本,并决定从头开始重新编写脚本。我已经删除了 ActiveSheet 并决定清理很多。完成后我会发布一个修订版。
  • 好的,在我发帖之前,你给我的脚本有错误。 Function FolderExists(ByVal path As String) As Boolean FolderExists = False Dim fso As New FileSystemObject If fso.FolderExists(path) Then FolderExists = True End Function 错误是编译错误:未定义用户定义类型。此fso As New FileSystemObject 已突出显示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
  • 2022-10-22
  • 1970-01-01
  • 1970-01-01
  • 2018-10-07
相关资源
最近更新 更多