VBA - Copy as Path - vba

I need help with a coding requirement that I've not previously experienced. I just browsed a similar issue raised here a couple of years ago - VBA to Copy files using complete path and file names listed in Excel Object.
My issue is similar but somewhat simpler than the OP.
I have a number of folders that each contain about 100 small .csv files; for each folder I need to copy the path for each file to an open worksheet. Each folder of .csv files has its own associated workbook.
As one example, the open workbook is F:\SM\M400AD.xlsm and the active worksheet is CSV_List. The folder containing the .csv files is F:\SM\M400AD.
Doing it manually, my sequence is then:
Open folder F:\SM\M400AD
Select all
Copy path
Paste to Range("B11") of worksheet CSV_List
When I do it manually, as described above, I get a list that looks like:
"F:\SM\M400AD\AC1.csv"
"F:\SM\M400AD\AC2.csv"
"F:\SM\M400AD\AE.csv"
"F:\SM\M400AD\AF.csv"
"F:\SM\M400AD\AG.csv"
"F:\SM\M400AD\AH1.csv"
"F:\SM\M400AD\AH2.csv"
"F:\SM\M400AD\AJ.csv"
and on down the page until I have a list of 100 paths. This single column list is then pasted into worksheet CSV_List, starting at Range("B11").
I need to automate this and would be grateful if a VBA guru could kindly code this for me.

Such of question has been asked before, for example:
Loop through files in a folder using VBA?
List files in folder and subfolder with path to .txt file
The difference is you want to "automate" it, which means you want to execute code on workbook Open event.
How to achieve that?
Open F:\SM\M400AD.xlsm file.
Go to Code pane (ALT+F11)
Insert new module and copy below code
Option Explicit
Sub EnumCsVFilesInCurrentFolder()
Dim sPath As String, sFileName As String
Dim i As Integer
sPath = ThisWorkbook.Path & "\"
i = 11
Do
If Len(sFileName) = 0 Then GoTo SkipNext
If LCase(Right(sFileName, 4)) = ".csv" Then
'replcae 1 with proper sheet name!
ThisWorkbook.Worksheets(1).Range("B" & i) = sPath & sFileName
i = i + 1
End If
SkipNext:
sFileName = Dir(sPath)
Loop While sFileName <> ""
End Sub
Now, go to ThisWorkbook module and insert below procedure:
Private Sub Workbook_Open()
EnumCsVFilesInCurrentFolder
End Sub
Save and close workbook
The workbook is ready to use. Whenever you open it, EnumCsVFilesInCurrentFolder macro will be executed.
Note: you have to change above code to restrict the number of records.

Related

How to open and activate another workbook in VBA?

I'm creating a macro where I will need to run it in 1 file (called "Masterfile"), it will open and execute the macro on another file ("SurveyReport") and then give me a message box saying "done!".
The code I have to execute on the SurveyReport file works fine when I open that file manually and execute it. The code I need to open SurveyReport from MasterFile is also working it seems, I ran the below with no issues:
Sub PivotTable()
'
' PivotTable Macro
Dim MasterFile As String
MasterFile = ActiveWorkbook.Name
Dim SurveyReport As String
SurveyReport = Application.GetOpenFilename("Excel files (*.xlsx), *xlsx", 1, "Please select the Survey Create Report file", , False)
Workbooks.Open (SurveyReport)
End Sub
But, when I try to activate the SurveyReport file so I can begin executing the macro in it, I get a "Subscript out of range" error. I've tried using the following code after the above block and before the code to execute in the SurveyReport file:
Windows(SurveyReport).Activate
This didn't work, not did:
ThisWorkbook.Activate
...which only had the effect of activating the MasterFile.
SurveyReport file is a .xlsx file. I tried saving it as a .xls file and amending the code, but no joy.
I also tried passing it the file name directly (i.e. Windows("filename.xlsx").Activate), same issue.
ActiveWorkbook is as it says on the tin - whichever workbook happens to be active when the code runs.
ThisWorkbook is always the workbook that the code is sitting in.
You can SET references to specific workbooks rather than just using their names each time. A name can change, or reference the wrong object.... imagine you have a friend called Darren. Each time you mention him you mention him by name. Someone that doesn't know Darren hasn't a clue which Darren out of all the ones available in the world you're talking about. Now imagine you have a little replica of Darren in your pocket... nah, that's a terrible anology - it wouldn't be a replica, it would be a reference to the real Darren... anyway, I digress.
This code sets a reference to the workbook, you can then use that reference any time you want to refer to the correct workbook:
Sub PivotTable()
Dim MasterFile As Workbook
Dim SurveyRptName As String
Dim SurveyReport As Workbook
Set MasterFile = ThisWorkbook '
SurveyRptName = Application.GetOpenFilename("Excel files (*.xlsx), *xlsx", 1, _
"Please select the Survey Create Report file", , False)
If SurveyRptName <> "False" Then
Set SurveyReport = Workbooks.Open(SurveyRptName)
End If
SurveyReport.Activate 'You don't need this line. It doesn't matter if
'the workbook is active, the code knows which one
'you're talking about in the next line.
MsgBox "This is " & SurveyReport.Name & _
" containing " & SurveyReport.Worksheets.Count & " sheets." & vbCr & _
"The value in cell A1 of the first sheet is " & _
SurveyReport.Worksheets(1).Range("A1")
End Sub
Edit: Of course, if you press Cancel when selecting a file then the lines following the IF...THEN code won't have a reference to work on and you'll get a Object Variable or With block variable not set - best not to run the bottom bit of code if you haven't successfully opened the Survey Report file.
The part of the answer that is missing - is that he tried to call a method of an object when his variable was STRING - the open command and subsequent commands will give you an OBJECT - which has properties and methods like .Activate. The STRING type has no such method or property (to be sure - it may have others).
the solution provided by Darren solves this by declaring his SurveyReport as type Workbook - an object of Excel.

Running an Access ImportExport from vbs fails if vbs is executed from Excel vba - any idea?

I have an Excel file (file1) with a macro that has this line:
Shell "wscript " & SFilename, vbNormalFocus
Where "SFilename" is the name of a vbs file.
In the vbs file I have a line:
appAccess.DoCmd.RunSavedImportExport ("ImportMonthlyData")
Above this line there are several lines like:
appAccess.DoCmd.OpenQuery ("Insert Detail")
And there is a lot of Excel work going on in the vbs on Excel file2 (not the same file that contains the wscript macro.
When I run the vbs file by double-clicking the vbs in file explorer, everything works great.
When I run the macro from within the Excel file1 via the macro, the vbs fails on the ImportExport line. The failure is that it cannot file the sheet in Excel from which to importexport, and the sheet name displayed in the error message has a "$" at the end of it. I don't know if the "$" is something Access does all the time, because it works when I use file explorer or if the "$" is being added on because of some other reason. However, my guess is this is not the problem.
I believe the problem arises because the ImportExport is trying to find the sheet in Excel file1 instead of file2.
What do you think? And if this is the problem, how do I rectify it?
So, you are trying to import Excel data to Access? Why now run the whole thing using VBA, which is a lot less cryptic, and much more intuitive, compared to running batch scripts.
Below is generic code to import the data from specific worksheets in all EXCEL files (worksheet names are the same in all files) that are located within a single folder. All of the EXCEL files' worksheets with the same worksheet names must have the data in the same layout and format.
Dim strPathFile As String, strFile As String, strPath As String
Dim blnHasFieldNames As Boolean
Dim intWorksheets As Integer
' Replace 3 with the number of worksheets to be imported
' from each EXCEL file
Dim strWorksheets(1 To 3) As String
' Replace 3 with the number of worksheets to be imported
' from each EXCEL file (this code assumes that each worksheet
' with the same name is being imported into a separate table
' for that specific worksheet name)
Dim strTables(1 To 3) As String
' Replace generic worksheet names with the real worksheet names;
' add / delete code lines so that there is one code line for
' each worksheet that is to be imported from each workbook file
strWorksheets(1) = "GenericWorksheetName1"
strWorksheets(2) = "GenericWorksheetName2"
strWorksheets(3) = "GenericWorksheetName3"
' Replace generic table names with the real table names;
' add / delete code lines so that there is one code line for
' each worksheet that is to be imported from each workbook file
strTables(1) = "GenericTableName1"
strTables(2) = "GenericTableName2"
strTables(3) = "GenericTableName3"
' Change this next line to True if the first row in EXCEL worksheet
' has field names
blnHasFieldNames = False
' Replace C:\Documents\ with the real path to the folder that
' contains the EXCEL files
strPath = "C:\Documents\"
' Replace 3 with the number of worksheets to be imported
' from each EXCEL file
For intWorksheets = 1 To 3
strFile = Dir(strPath & "*.xls")
Do While Len(strFile) > 0
strPathFile = strPath & strFile
DoCmd.TransferSpreadsheet acImport, _
acSpreadsheetTypeExcel9, strTables(intWorksheets), _
strPathFile, blnHasFieldNames, _
strWorksheets(intWorksheets) & "$"
strFile = Dir()
Loop
Next intWorksheets
Apparently, Excel is looking in file2 for the worksheet. I'm not sure why, but as a work around, I simply copied the needed worksheet from file1 to file2, completed the necessary work and then deleted the worksheet.

Excel VBA macro - Change link name

I have a excel macro routine that I need to prep a file for another routine which is run daily. This prepping involves changes the links of t-1 file to a t0 file.
The code I usually do is:
ActiveWorkbook.ChangeLink Name:= _
"file path", NewName:=new_file_path, Type:=xlExcelLinks
My trouble now is that for this particular routine the file path to be changed to a new routine is not always the same, thus I would need a way to automatize finding out what are the current links to replace them all. The new file path I now because it is the worksheet that is calling this routine and opening this file, so first thing I do Is
new_file_path = "C:\...."& ActiveWorkbook.Name & ".xlsm"
What would help me is if there is a trick to replace all links for a new one, without the need to say the name/path of the old links. Does any one know?
Thanks
To change all the excel links in a workbook try this procedure:
Sub WbThs_ChangeLink_Excel()
Dim wbTrg As Workbook
Dim sLinkNew As String
Dim aLinks As Variant, vLink As Variant
sLinkNew = "##VBA Links Replace - Target 3.xlsb" 'Change as required
Set wbTrg = ThisWorkbook 'Change as required
Rem Set array with all excel links
aLinks = ActiveWorkbook.LinkSources(xlExcelLinks)
Rem Replace each excel Link
If Not IsEmpty(aLinks) Then
For Each vLink In aLinks
wbTrg.ChangeLink Name:=vLink, NewName:=sLinkNew, Type:=xlExcelLinks
Next: End If
End Sub
See the following pages for additional information on the resources used:
Workbook.ChangeLink Method (Excel)
Workbook.LinkSources Method (Excel)
XlLink Enumeration (Excel)

Excel macro to open a folder of excel workbooks and copy 1 cell

I have a folder of .xlsx files, each identical in layout.
I need to write a macro in excel to open each file in turn (100+ files)
then get the data (a name) from a single cell, and drop it in a new excel worksheet, move on to the next and insert that below the last one etc.
Giving me basically a list of names from data not file names)
Here is (pretty much) exactly what you're trying to do. Next time do a little bit of googling before you ask! :)
http://www.excel-easy.com/vba/examples/files-in-a-directory.html
ROUGH CODE UNSURE IF IT WILL WORK: But here is the basic idea of what you need to modify in the example I sent you. If you look at the example again, it does everything you need and then some. Since you weren't interested in all worksheets, you don't have to loop through all worksheets in a workbook. You can just open it up, read your cell of interest, and then close it. The Do While loop will do this for every Excel file in your directory. AGAIN! Please modify this example accordingly before you use it.
Dim directory As String, fileName As String, sheet As Worksheet, i As Integer, j As Integer
Application.ScreenUpdating = False
directory = "c:\test\"
fileName = Dir(directory & "*.xl??")
Do While fileName <> ""
i = i + 1
Workbooks.Open (directory & fileName)
Workbooks("files-in-a-directory.xls").Worksheets(1).Cells(i, 1).Value = Workbooks(fileName).Worksheets(1).Cells(x, y) <-- whatever your cell of interest is
Workbooks(fileName).Close
fileName = Dir()
Loop
Application.ScreenUpdating = True

Excel macro: How to extract data from other Excel file [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
excel macro: browse excel file and use its worksheet data
In brief, I want to write a script can do this.
In the current excel file, there is a macro button. The user can click the button to browse files (another Excel). In that browsed Excel, several worksheets will be load to current Excel workbook and the data will be used.
I write like this
Sub Button1_Click() ' choose LOAD path
objFile = Application.GetOpenFilename(fileFilter:="All Files (* . *) , * . * ") ' browse function
... ' following
Call main_function
End Sub
I write the browse function already. but how to write the following part? eg. the certain worksheet's data in objFile will be used in main_function.
While what you want isn't really clear (I'm not confident I understand your question's intent) I will have a crack at this.
Assuming you have the name of the file you'd like to open in objFile, you can go about extracting data from that spreadsheet like this - I just open the selected workbook, then write the name of all of the sheets in it to Column A in whichever sheet was open before the button was pressed.
Opening a new workbook causes it to be brought to the foreground - so if I didn't grab the active sheet before opening a new book, then set it after opening the new one, you'd end up overwriting data in the workbook you just opened.
Sub Button1_Click()
' choose LOAD path
objFile = Application.GetOpenFilename(fileFilter:="All Files (* . *) , * . * ") ' browse function
Set curSheet = ActiveSheet
Set mWorkbook = Workbooks.Open(objFile)
curSheet.Activate
Call someFunction(curSheet, mWorkbook)
End Sub
Sub someFunction(targetSheet, srcWorkbook)
numSheets = srcWorkbook.Sheets.Count
For i = 1 To numSheets
targetSheet.Cells(i, 1) = srcWorkbook.Sheets(i).Name
Next i
End Sub