[英]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.