简体   繁体   English

使用变量存储文件路径,然后使用变量打开,复制,粘贴和关闭工作簿

[英]Using a variable to store a filepath and then open, copy, paste & close workbooks with the variable

So I am trying to give the user the ability to select a file from which I want to import (copy & paste) the contents from worksheets in that file into the current workbook. 所以我试图让用户能够选择一个文件,我想从中将该文件中的工作表中的内容导入(复制和粘贴)到当前工作簿中。 I have been able to do so by hardcoding the filepath into the code but am having trouble doing the same with a variable to hold the filepath of the selected file before opening, copying, pasting and closing the file. 我已经能够通过将文件路径硬编码到代码中来实现这一点,但是在打开,复制,粘贴和关闭文件之前,我无法使用变量来保存所选文件的文件路径。 All of the latter works fine, I'm just stuck on the variable part. 所有后者都工作正常,我只是坚持变量部分。

Like I said I have been able to do it by hardcoding the filepath into the open & close subs (youll see what i mean in a minute) but dont know how to go about setting and using the variable across different subs 就像我说的那样,我已经能够通过将文件路径硬编码到开放和关闭子(你会在一分钟内看到我的意思)来做到这一点但不知道如何设置并在不同的子设备中使用变量

Option Explicit
Public InputFile As String

Sub OpenWorkbook()
    'attempt to let the variable equal to the filepath in a cell
    Worksheets("Input_Parameters").Range("F9").Value = InputFile
    'I was able to reference directly the hardcoded filepath here, having an issue with putting it in a variable
    Workbooks.Open InputFile
End Sub

Sub CloseWorkbook()
    'this will need altering also
    Workbooks("InputFile").Close SaveChanges:=True
End Sub

Sub SelectInput()
     Dim FileSelect As Variant
     Dim wb As Workbook
     Dim i As Integer
     Application.ScreenUpdating = False
     FileSelect = Application.GetOpenFilename(filefilter:="Excel Files,*.xl*", _
     MultiSelect:=False)
     If FileSelect = False Then
     MsgBox "Select the file name"
     Exit Sub
     End If
     Worksheets("Input_Parameters").Range("F9").Value = FileSelect
     'attempting to let the value equal a global variable
     Set InputFile = FileSelect
End Sub


Sub Import()
    Dim PRC As String
    PRC = Worksheets("Input_Parameters").Cells(17, "B").Value

OpenWorkbook
'this first reference is what I was playing with, the rest is what worked when hardcoded
Workbooks("InputFile").Worksheets("Run_Map").Range("A2:Z500").Copy _
ThisWorkbook.Worksheets("Run_Map").Range("A2:Z500")

Workbooks("Mock_OneSourceOfTruth_1.xlsx").Worksheets("Reporting_Map").Range("A2:Z500").Copy _
ThisWorkbook.Worksheets("Reporting_Map").Range("A2:Z500")

Workbooks("Mock_OneSourceOfTruth_1.xlsx").Worksheets("Variable_Map").Range("A2:Z500").Copy _
ThisWorkbook.Worksheets("Variable_Map").Range("A2:Z500")

Workbooks("Mock_OneSourceOfTruth_1.xlsx").Worksheets("Product_Map_" & PRC).Range("A2:Z500").Copy _
ThisWorkbook.Worksheets("Product_Map_ETY").Range("A2:Z500")

Workbooks("Mock_OneSourceOfTruth_1.xlsx").Worksheets("Subproduct_Map").Range("A2:Z500").Copy _
ThisWorkbook.Worksheets("Subproduct_Map").Range("A2:Z500")

Workbooks("Mock_OneSourceOfTruth_1.xlsx").Worksheets("Currency_Map").Range("A2:Z500").Copy _
ThisWorkbook.Worksheets("Currency_Map").Range("A2:Z500")

Workbooks("Mock_OneSourceOfTruth_1.xlsx").Worksheets("FX_Map").Range("A2:Z500").Copy _
ThisWorkbook.Worksheets("FX_Map").Range("A2:Z500")

CloseWorkbook
End Sub

Im comfortable with all the code and how it works, I just want some guidance about the variables, what ways can I do this? 我对所有代码及其工作方式感到满意,我只是想要一些关于变量的指导,我可以用这些方法做什么? declare the variable globally? 全局声明变量? how can I do that? 我怎样才能做到这一点? any other options? 还有其他选择吗? Can I even reference the filepath in the OpenWorkbook() sub as a variable rather than the hardcoded filepath? 我甚至可以将OpenWorkbook()子文件中的文件路径引用为变量而不是硬编码文件路径吗?

Whenever I need to copy data, I find it incredible helpful to stick to concise variable handling, ie one variable for the source - whatever (eg workbook, worksheet, range, cell, row index, column index, etc.), and one for the target. 每当我需要复制数据时,我发现坚持简洁的变量处理是非常有帮助的,即源的一个变量 - 无论是什么 (例如工作簿,工作表,范围,单元格,行索引,列索引等),还有一个用于目标。

Second, I would recommend to keep variables as private as possible. 其次,我建议将变量尽可能保密。 If you want to communicate a value as a result of Sub , change that Sub into a Function and let the result be the return value of that function. 如果你想作为的结果进行通信的价值Sub ,更改Sub成一个Function ,让结果是函数的返回值。

Lastly, it also helps to keep every subroutine of a macro that is not explicitly meant to be called from other macros as well Private , so that every macro has its own separate scope within its module file. 最后,它还有助于保留宏的每个子例程,这些子例程并非明确地从其他宏调用,也是Private ,因此每个宏在其模块文件中都有自己独立的范围。

That being said, I think the code you're looking for looks something like this: 话虽这么说,我认为你正在寻找的代码看起来像这样:

Option Explicit

' Entry point of macro
Sub Import()
    Dim SourceWb As Workbook
    Dim TargetWb As Workbook

    ' Prevents Excel from showing the opening and closing
    Application.ScreenUpdating = False

    ' The target is this workbook
    Set TargetWb = ThisWorkbook

    ' Let the user select the workbook
    Set SourceWb = OpenSourceWorkbook
    If SourceWb Is Nothing Then
        ' The user has cancelled the selection.
        ' We can be fairly sure they'll assume that clicking "Cancel"
        ' cancels the operation, so we can just exit the macro
        ' without further notice.

        Application.ScreenUpdating = True
        Exit Sub
    End If

    If SourceWb Is TargetWb Then
        MsgBox "Cannot copy from and to the same workbook." & vbCrLf & vbCrLf & _
            "Cancelling the import.", vbExclamation, "Invalid source file"

        Application.ScreenUpdating = True
        Exit Sub
    End If

    ' Store whether so far everything worked
    Dim Success As Boolean

    ' Copy the desired data, but stop if something goes wrong
    Success = CopyData(SourceWb, TargetWb, "Run_Map", "A2:Z500")
    If Success Then Success = CopyData(SourceWb, TargetWb, "Reporting_Map", "A2:Z500")
    If Success Then Success = CopyData(SourceWb, TargetWb, "Variable_Map", "A2:Z500")
    If Success Then Success = CopyData(SourceWb, TargetWb, "Product_Map_ETY", "A2:Z500")
    If Success Then Success = CopyData(SourceWb, TargetWb, "Subproduct_Map", "A2:Z500")
    If Success Then Success = CopyData(SourceWb, TargetWb, "Currency_Map", "A2:Z500")
    If Success Then Success = CopyData(SourceWb, TargetWb, "FX_Map", "A2:Z500")

    ' Close the user-selected source workbook
    Call SourceWb.Close(SaveChanges:=False)

    If Success Then
        MsgBox "All data was copied successfully.", vbInformation, "Success"
    End If
    ' In the other case we triggered a message box earlier,
    ' so no need to report that again.

    ' Re-enable the screen updating - and we're done!
    Application.ScreenUpdating = True
End Sub

Private Function OpenSourceWorkbook() As Workbook
    Dim SelectedFilePath As Variant

    SelectedFilePath = Application.GetOpenFilename(filefilter:="Excel Files,*.xl*", _
    MultiSelect:=False)

    If SelectedFilePath = False Then
        ' The user has cancelled the dialog
        ' Set the result to Nothing
        Set OpenSourceWorkbook = Nothing
    Else
        ' Open the file and set it as result
        Set OpenSourceWorkbook = Workbooks.Open(SelectedFilePath)
    End If

End Function

Private Function CopyData(SourceWb As Workbook, TargetWb As Workbook, _
        WorksheetName As String, Range As String) As Boolean

    Dim SourceWs As Worksheet
    Dim TargetWs As Worksheet
    Dim SourceArea As Range
    Dim TargetArea As Range

    ' Try to obtain the source worksheet
    Set SourceWs = TryGetWorksheetByName(SourceWb, WorksheetName)
    If SourceWs Is Nothing Then
        ' Source worksheet not found. Report error and abort.
        MsgBox "The file you selected does not appear to be a valid source for the data." & vbCrLf & _
            "It does not have a worksheet named '" & WorksheetName & "'." & vbCrLf & vbCrLf & _
            "Cancelling the import.", vbExclamation, "Invalid source file"

        ' Return failure
        CopyData = False
        Exit Function
    End If

    ' Try to obtain the target worksheet
    Set TargetWs = TryGetWorksheetByName(TargetWb, WorksheetName)
    If TargetWs Is Nothing Then
        ' Target worksheet not found. Report error and abort.
        MsgBox "Cannot copy the data to the target workbook since it" & vbCrLf & _
            "does not have a worksheet named '" & WorksheetName & "'." & vbCrLf & vbCrLf & _
            "Cancelling the import.", vbExclamation, "Invalid target file"

        ' Return failure
        CopyData = False
        Exit Function
    End If

    ' Range to copy from and to
    Set SourceArea = SourceWs.Range(Range)
    Set TargetArea = TargetWs.Range(Range)

    ' Finally, copy the data
    Call SourceArea.Copy(Destination:=TargetArea)

    ' Return success
    CopyData = True
End Function

Private Function TryGetWorksheetByName(Wb As Workbook, WorksheetName As String) As Worksheet
    Set TryGetWorksheetByName = Nothing
    On Error Resume Next
        Set TryGetWorksheetByName = Wb.Sheets(WorksheetName)
    On Error GoTo 0
End Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM