VBA:如何同时引用两个工作簿中的单元格

时间:2016-10-11 09:51:20

标签: excel vba excel-vba

我正在编写一个宏来将数据从报告文件移动到主文件中。我的初始版本有效,但它很慢并且闪烁很多。这并不奇怪,因为我正在使用Workbook.Activate()。我故意这样做,原因很简单并且有助于调试。

但是,现在它正常运行,我想停止使用Workbook.Activate()

如何在两个单独的工作簿中引用单元格而不是实际上每个单元格中的单元格?我不介意在开始的时候做几次闪光,但在那之后我不想再那样了。

我在一个简单的测试子中试过这个:

Sub try()
    Dim c As Range
    Dim c1 As Range

    Workbooks(MASTER_FILE_NAME).Activate
    Set c = Cells(25, 1)
    Workbooks(REPORT_FILE_NAME).Activate
    Set c1 = Cells(10, 1)
    c.Value = c1.Value

    Set c = Cells(c.Row + 1, c.COLUMN)
    Set c1 = Cells(c1.Row + 1, c.COLUMN)
    c.Value = c1.Value
End Sub

但第三个块只是将两个范围设置为指向报告文件中的单元格。我需要使用命名范围吗?我真的不愿意。还有另一种方式吗?

3 个答案:

答案 0 :(得分:2)

MMMM DD, YYYY

记住“cells”假定为“activewrokbook.activesheet。”

答案 1 :(得分:1)

要停止闪烁,你可以使用它(虽然它会因缺少工作簿的变化而停止,但这是一个很好的习惯,可以提高性能):

With Application.Excel
    .ScreenUpdating = False
    .DisplayStatusBar = False
    .Calculation = xlCalculationManual
    .EnableEvents = False
End With

要回答有关同时参考的问题,不能完全同时进行,但皮埃尔的说法是正确的:

Set c = Workbooks(MASTER_FILE_NAME).sheets("azzeetr").Cells(25, 1)
Set c1 = Workbooks(REPORT_FILE_NAME).sheets("dfdsfvsdfvs").Cells(10, 1)

使用此功能,您不会在活动工作表之间进行更改,只需在不同的工作簿中引用单元格。

我用这个:

With Application.Excel
    .ScreenUpdating = False
    .DisplayStatusBar = False
    .Calculation = xlCalculationManual
    .EnableEvents = False
End With
Set c = Workbooks(MASTER_FILE_NAME).sheets("azzeetr").Cells(25, 1).offset(1,0)
Set c1 = Workbooks(REPORT_FILE_NAME).sheets("dfdsfvsdfvs").Cells(10, 1).offset(1,0)
c.Value = c1.Value
With Application.Excel
    .ScreenUpdating = True
    .DisplayStatusBar = True
    .Calculation = xlCalculationAutomatic
    .EnableEvents = True
End With

答案 2 :(得分:1)

There won't be any screen activity if you don't use .Activate or .Select, so no need to turn off the screen update for the moment (only if you have a lot of data to transfer)

You should simply create Workbook and Worksheet objects to let the code which one you are using :

Sub try()
    Dim wB1 As Workbook
    Dim wB2 As Workbook
    Dim wS1 As Worksheet
    Dim wS2 As Worksheet
    Dim c1 As Range
    Dim c2 As Range

    Dim MASTER_FILE_NAME As String
    MASTER_FILE_NAME = "Workbook_MASTER_Name.xlsm"
    Dim REPORT_FILE_NAME As String
    REPORT_FILE_NAME = "Workbook_REPORT_Name.xlsm"


    'Set wB1 = ThisWorkbook
    'Set wB1 = ActiveWorkbook
    Set wB1 = Workbooks(MASTER_FILE_NAME)
    Set wB2 = Workbooks(REPORT_FILE_NAME)

    Set wS1 = wB1.Sheets("Master_Sheet_Name")
    Set wS2 = wB2.Sheets("Report_Sheet_Name")


    Set c1 = wS1.Cells(25, 1)
    Set c2 = wS2.Cells(10, 1)

    'Put the data of the master in report
    c2.Value = c1.Value

    Set c1 = c1.Offset(1, 0)
    Set c2 = c2.Offset(1, 0)

    c2.Value = c1.Value
End Sub

Or you can do this with a Range of Cells directly (much more efficient and fast!) :

Sub try_ranges()
    Dim wB1 As Workbook
    Dim wB2 As Workbook
    Dim wS1 As Worksheet
    Dim wS2 As Worksheet
    Dim c1 As Range
    Dim c2 As Range
    Dim LastRow1 As Long


    Dim MASTER_FILE_NAME As String
    MASTER_FILE_NAME = "Workbook_MASTER_Name.xlsm"
    Dim REPORT_FILE_NAME As String
    REPORT_FILE_NAME = "Workbook_REPORT_Name.xlsm"


    'Set wB1 = ThisWorkbook
    'Set wB1 = ActiveWorkbook
    Set wB1 = Workbooks(MASTER_FILE_NAME)
    Set wB2 = Workbooks(REPORT_FILE_NAME)

    Set wS1 = wB1.Sheets("Master_Sheet_Name")
    Set wS2 = wB2.Sheets("Report_Sheet_Name")

    'Get the last used row in column A in your master sheet
    LastRow1 = wS1.Range("A" & wS1.Rows.Count).End(xlUp).Row

    'Take the whole column in master sheet
    Set c1 = wS1.Range(wS1.Cells(25, 1), wS1.Cells(LastRow1, 1))

    'Resize the range in report sheet to fit what you have taken in master sheet
    Set c2 = wS2.Cells(10, 1).Resize(c1.Rows.Count, 1)

    'Transfer the values with high efficiency! ;)
    c2.Value = c1.Value
End Sub