从不同的工作表调用子时抛出 400

Posted

技术标签:

【中文标题】从不同的工作表调用子时抛出 400【英文标题】:400 thrown when sub called from different sheet 【发布时间】:2018-12-01 14:01:44 【问题描述】:

我遇到了一个非常奇怪的 400 错误,我无法解释。

我有两张纸

    Reconciliation Reporting(指向子“ThisWorkbook.ImportRawData”的按钮 Trading Day Processes,实际在其上进行导入,还有一个指向“ThisWorkbook.ImportRawData”的按钮

当我单击 Sheet Trading Day Processes 中的按钮时,一切正常。当在 Sheet Reconciliation Reporting 中单击按钮时,会出现 400。

我已经追踪了错误。当我将这部分注释掉时,一切正常。我找不到这个 400 错误的原因,以下部分可能导致。

tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeTop).LineStyle = xlContinuous
tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeTop).Weight = xlThick
tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeBottom).LineStyle = xlContinuous
tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeBottom).Weight = xlThick
tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeLeft).LineStyle = xlContinuous
tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeLeft).Weight = xlThick
tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeRight).LineStyle = xlContinuous
tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeRight).Weight = xlThick 

ImportRawData sub(我已经删掉了与这个错误无关的代码。

Sub ImportRawData()
' main function to importing from _data into Trading Day Processes
    Dim Workbook As Workbook
    Set Workbook = ThisWorkbook
    Set tradingDaySheet = Workbook.Worksheets("Trading Day Processes")

    ' variable needed for importing data
    Dim i As Integer
    Dim m As Integer
    Dim TDcurrentRow As Long
    Dim DAnumDataRows As Integer
    Dim MANnumDataRows As Integer
    Dim TDstartRow As Long
    Dim TDendRow As Integer
    Dim currentDatai As Integer
    ' variable to check if a row was importet successfully
    Dim importStatus As Boolean

    ' set the starting row in the Trading Day Processes Sheet
    TDstartRow = 11
    TDcurrentRow = TDstartRow
    ' get the amount of rows to import
    DAnumDataRows = CountDataRows
    ' set the end row
    TDendRow = TDstartRow + DAnumDataRows

    ' get the mount of rows for manual entries
    MANnumDataRows = CountManualRows



    ' check if the sheet is clean otherwise throw message
    If IsEmpty(tradingDaySheet.Range("C11").Value) = True Then

         ' Import Automatic processes
        For i = 1 To DAnumDataRows
            importStatus = ImportNextRow(i, TDcurrentRow, False)
            TDcurrentRow = TDcurrentRow + 1
        Next i

        ' Import Manual processes
        For m = 1 To MANnumDataRows

            importStatus = ImportNextRow(m, TDcurrentRow, True)
            TDcurrentRow = TDcurrentRow + 1
        Next m

        ' Create End of Day Balance
        CreateEndOfDayRow (TDcurrentRow)

        ' Create P&L Sheet
        'CreatePandLReporting (TDstartRow,TDcurrentRow)

    Else
        MsgBox "The _data sheet has not been cleared. Please clean the sheet first."
    End If
    MsgBox "Import Done. Happy reconciling"

End Sub

Sub 调用函数 CreateEndOfDayRow()。我已经删掉了一些与这个错误无关的代码(否则太长了):

Function CreateEndOfDayRow(lastRow As Long)
' The function creates the end of day balance after all intraday processes have been imported
    Dim Workbook As Workbook
    Set Workbook = ThisWorkbook
    Set dataSheet = Workbook.Worksheets("_data")
    Set tradingDaySheet = Workbook.Worksheets("Trading Day Processes")
    Dim startRow As Integer
    Dim startRowIncStartBalance As Integer
    Dim rowDiff As Integer
    startRowIncStartBalance = 10
    startRow = 11

    ' calc difference between first and last row for automatic formulas
    rowDiff = lastRow - startRow
    rowDiffIncStartBalance = lastRow - startRowIncStartBalance

    tradingDaySheet.Cells(lastRow, 1).Value = "EOD Balance"

    tradingDaySheet.Cells(lastRow, 70).NumberFormat = FormattingModule.FormatHelper("Percentage")


    ===== CUT OUT CODE =======

      ====>The following lines seem to cause the error

     ' put fat boarder around balances
     tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeTop).LineStyle = xlContinuous
     tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeTop).Weight = xlThick
     tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeBottom).LineStyle = xlContinuous
     tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeBottom).Weight = xlThick
     tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeLeft).LineStyle = xlContinuous
     tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeLeft).Weight = xlThick
     tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeRight).LineStyle = xlContinuous
     tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70)).Borders(xlEdgeRight).Weight = xlThick

     SetLastRow (lastRow)

End Function

也许这与错误使用工作表有关?如上所述,当从同一张表中调用 Sub 时,一切正常。

【问题讨论】:

【参考方案1】:

很可能是因为

tradingDaySheet.Range(Cells(lastRow, 1), Cells(lastRow, 70))....

所有这些 Cells Range 引用都隐式ActiveSheet 作为工作表引用限定,而您需要它是tradingDaySheet

因此解决方案将在您的 Range 对象中使用 显式 Worksheet 引用

tradingDaySheet.Range(tradingDaySheet.Cells(lastRow, 1), tradingDaySheet.Cells(lastRow, 70))....

等等

使用With ... End With 语法是一种更优雅(更简洁)的方法:

With tradingDaySheet ' reference wanted sheet object
    .Range(.Cells(lastRow, 1), .Cells(lastRow, 70)).... ' all object references beginning with a dot (`.`) are implicitly referencing the object in the `With` statement
    ....
End With

可以进一步推到:

With tradingDaySheet ' reference wanted sheet object
    With .Range(.Cells(LastRow, 1), .Cells(LastRow, 70)) ' reference referenced sheet Range object
        .Borders(xlEdgeTop).LineStyle = xlContinuous
        .Borders(xlEdgeTop).Weight = xlThick
        .Borders(xlEdgeBottom).LineStyle = xlContinuous
        .Borders(xlEdgeBottom).Weight = xlThick
        .Borders(xlEdgeLeft).LineStyle = xlContinuous
        .Borders(xlEdgeLeft).Weight = xlThick
        .Borders(xlEdgeRight).LineStyle = xlContinuous
        .Borders(xlEdgeRight).Weight = xlThick
    End With
End With

【讨论】:

谢谢,这是个错误。在每个单元之前添加tradingDaySheet.

以上是关于从不同的工作表调用子时抛出 400的主要内容,如果未能解决你的问题,请参考以下文章

动态执行从 SSIS 到 SSMS 中不同表的不同表结构的 Excel 包工作表?

从excel单元格调用excel工作表函数

从不同的 Excel 工作表自动导入 SQL 表

将excel工作表数据从excel vba传输到访问表给出错误

从 vba 代码调用 Excel 的工作表函数

如何将 Excel 数据从不同的工作表导出到 SQL-SERVER 数据库?