I have vba that works great to open a file based of a partial criteria met. but when I have multiple files open the file opening by the below VBA remains open when done and I am having trouble how to call that workbook back to close it seeing it opens off partial parameters being met. in quick summary the opencopy (opens a file), then in another vba I copy that data, and pastes it into another workbook (done in another VBA) when done i want to bring that workbook back up and just close it. if i do activeworkbook.close it closes the workbook i'm working on which i don't want. Help im stuck!
Sub OpenCopy()
Dim sPath As String
Dim sPartial As String
Dim sFName As String
sPath = "C:\" ' <<<<< change accordingly
sPartial = "AAA_" & Year(Now) & IIf(Len(Month(Now)) = 1, "0" & Month(Now), Month(Now)) &
IIf(Len(Day(Now)) = 1, "0" & Day(Now), Day(Now)) & "*.txt"
sFName = Dir(sPath & sPartial)
If Len(sFName) > 0 Then
Workbooks.OpenText sPath & sFName
Else
MsgBox "File not found.", vbExclamationEnd If
End Sub
Your problem is in "the other VBA". Try to force your project to comply with the rules by which VBA works.
That would mean to acknowledge that there is only one VBA. That VBA has procedures. You can call these procedures manually (which you probably do, and which leads you to talk of "the other VBA") or you can create a Main procedure that calls them for you, one after the other. The advantage of this would be that you can declare objects and variables in the Main which could be made available to all procedures, passed as arguments.
So, you would open a file, finding it by an abbreviated description of its name. You would assign this file to a variable, say File1, and now you could refer to it from anywhere in your project to read or copy from and to close it. You never need to know its name because you refer to it by the variable name to which it was assigned. VBA will assure that the name is unique.
As an alternative, you could of course take the file's complete name from the file after it was opened and then close the file by its complete name. In fact, the Dir function in your code does provide the complete name. So you could take it from there even before the file is opened. As I said, the problem is that the name would be in "the other VBA", an idea that isn't supported by VBA.
But, presuming that you want to continue with your piecemeal approach at least for the moment, wouldn't you be able to identify the file by the same partial details that led you to find it in the first place? I presume that the names of files you have open at the same time would differ in the "AAA" part. So, If Instr(ActiveWorkbook.Name, "AAA") = 1 Then would identify a file. You could loop through all open workbooks with For Each Wb In Application.Workbooks and check each name. You may have to add an input box to enter "AAA" another time because your different "VBAs" can't be made to talk to each other.
By the way, your beautiful partial string could be simplified using VBA's Format function. Try this.
sPartial = "AAA_" & format(date, "yyyymmdd")
Related
The macro I wrote - it pulls information from two different spreadsheets and formats it all. Those spreadsheets will change every month. How do I get the "ACTIVATE" command to reference the worksheet I have open instead of the one that WAS open when I recorded this macro? One of the commands loos like this:
Windows("273517_0273517M190831_08_31_2019_Toll Detail.csv").Activate
I tried to copy and paste a few lines of the code but THIS site rejected it, saying it wasn't formatted properly. Since it was an exact copy of a fully functioning macro - I haven't got a clue what it wants.
It is the "...Toll Detail.csv" file in line 4 that needs to be a variable as it changes monthly. This file is referenced several times in my recorded macro. I will need to be able to go in and change each of them in whatever manner you suggest. I am TOTALLY NEW to VBA so please, dumb it down as best you can. :) Thank you!
You can use GetOpenFileName to select and open your file each time. Following is the code for your reference:
Sub OpenFile()
Dim myFile As String
Dim Wb As Workbook
myFile = Application.GetOpenFilename("CSV Files (*.csv), *.csv")
'Exit if no file selected
If myFile = "False" Then
MsgBox "No file selected!"
Exit Sub
End If
'Open the file
Set Wb = Workbooks.Open(myFile)
'Do what you want with the file here onward
'
'
'
End Sub
I would suggest declaring a variable in the beginning of the sub, like so:
Dim strFile As String
strFile = "273517_0273517M190831_08_31_2019_Toll Detail.csv"
Throughout the sub you can reference the variable, so in every instance where there is the workbook name in the code replace it with strFile like this:
Windows(strFile).Activate
That way you only have to update it once for the entire procedure.
There might be more elegant solutions, but more information on the use case would be required for that.
So, essentially I export a data set from a website and the data set comes in an excel file. The file is always named as such "Task_State_(Pivot)_xxxxxx" X's are a random string of numbers. The work I do involves me having 2 excel files open, including the downloaded file and taking the downloaded one (task_State_(Pivot)) and taking that data and copying it in my other excel file, which acts as my masterfile of sorts. My question is, how do I select that workbook if I don't know the full name of it because of the random string of numbers at the end? I can't really activate the workbook because I don't have the full name since it always changes. Any suggestions?
Dim wb As Workbook
For Each wb In Application.Workbooks
If wb.Name <> "your_file_name" Then
'do whatever you want ot do with your other wb
End If
Next wb
The answer above is a good start, but I'd add stuff to allow the user to confirm the correct sheet name once at the start:
Note: you may have other spreadsheets open or if you are using macros, you may also have a personal macro workbook open (in the background) - you don't want to write to that.
create a global variable to hold the name of the workbook that you are working on today, and the first time code tries to open it, get the user to confirm the name:
eg: Dim strGlobalNewWorkbook As String
inside the loop (and the if) that Michal Rosa suggests, put code that does this:
If MsgBox("please confirm that you want to process workbook: " & wb.Name, vbOKCancel) = vbOK Then
strGlobalNewWorkbook = wb.Name
Exit Sub
End If
then you can access the correct workbook from code using the format:
Application.Workbooks(strGlobalNewWorkbook).Name ' eg: get the name back
I'm making a macro in excel 2010 and my goal is that everyone can use this macro for their own work. Therefore I have to make it very flexible.
Everyone names their own workbook (I've solved this in the macro by using ThisWorkbook), but everyone also names their own extraction file (from where the new data comes).
However, almost no-one knows how to work with VBA so it's not possible to adjust this reference in the code every time.
Therefore, I've added a new sheet: 'Personalize'
In here, the person can add the name of the extraction file in a specific cell.
Unfortunately I don't know how to open a workbook that has the name of a specific cell in the current workbook.
I tried, for example, Windows("ThisWorkbook.Sheets("Personalize").Range("B3")").Activate but it didn't work.
The same thing with sheets that can be named differently, I don't know how to adjust them in the macro without using VBA in every case.
Does anyone have any ideas or suggestions?
Thank you so much in advance!
Kind Regards,
Hendrik
If you want to open a workbook that's closed you need the full path:
dim wkb as workbook
dim wbPath as String
wbPath = ThisWorkbook.Sheets("Personalize").Range("B3").value
Set wkb = Workbooks.Open(wbPath )
If you want to activate a workbook that's already opened, you don't need the full path but the workbook's name (such as "Workbook1.xlsx"). For this you can shave off the path before reaching "Workbook1.xlsx" (alternatively if the workbook is always going to be opened first, just have them enter the workbook's name directly and skip taking out the rest of the path):
dim wbname as String
wbname = ThisWorkbook.Sheets("Personalize").Range("B3").value
Do until Instr(wbname, "\") = 0
wbname = Mid(wbname, instr(wbname, "\") + 1) 'I didn't test this, just going off the top of my head
Loop
Workbooks(wbName).Activate
Be sure to handle your errors properly. For reference: VBA Excel simple Error Handling
Test what happens when you try to input a name that's incorrect, for example. You want to handle those errors with appropriate messageboxes or the users may feel like your program doesn't work.
I am almost completely new to using VBA and Macros on Excel 2010. I know little to nothing about macro coding, and I just started a day ago trying to pick it up.
I was asked to create a macro that copies ONLY the data from 12 workbooks and pastes it onto a blank workbook (they all have 1 sheet each, with the data on each workbook starting on cell A3 while stretching to column S (the amount of data on the sheets vary)).
NOTE: When I mean "ONLY the data," the cells that I want to be copied include the blank cells that are in between the first and last parts of the data.
1) When copying data from one workbook to another, do you HAVE to specify the cells that you would like to copy? Or is there a way to specify where the data ends on the sheet, and then copy all of that data? If so, then could someone show me how to do so? The reason for doing so is because the macro will be used weekly.
and 2) Could someone simply help me develop this macro? Help would be massively appreciated :)
Some Extra Notes:
- The Workbooks are named "Status by offering ID [1-12]
Thanks again!
Ripster has given one example of missing information from your specification.
Santosh recommends a pretty neat tool but my reading of your question is that your knowledge is not up to using a tool yet.
I deduce this is a work question and your boss has asked you to write this macro despite your knowledge of VBA being zero. This seems to be a growing problem: you can discover the answer to anything on the net so why bother with training people. Even if you produced a complete specification of your requirement, I doubt anyone will give you a complete solution. If they do provide a complete solution, it will not help with the next requirement. So I am going to break your problem down into the type of questions you can ask the net.
Each week you get 12 source workbooks and create a summary by consolidating data from the source workbooks. Do you overwrite the previous week's summary with the new summary or do you want to save all the summaries? It will not add much to the complexity to keep all the summaries but you need to decide what you want.
If you discard the previous summary, the macro can be in Summary.xlxm, say. If you save the summaries, the macro will need to be in its own workbook, Macro.xlsm say, and it will create a different summary workbook, SummaryYYWW.xlsm say, each week.
If you search for "Workbook Open" and "Workbook Create", you will find instructions on how a macro in one workbook can open other workbooks and create new workbooks.
Where are the source workbooks? Are they in the folder CurrentData which is overwritten each week? Are they in the folders Week1301, Week1302, Week1303 and so on? Are they in the folder NewData and the macro is to move them to folders Week1301, Week1302, Week1303 and so on after processing? All these are options but I suggest you start by moving the source and summary workbooks to/from a folder convenient for the macro.
Look up "ThisWorkbook" and "ActiveWorkbook". In brief: "ThisWorkbook" is the workbook containing the macro and "ActiveWorkbook" is the most recently opened workbook.
Look up workbook property "Path". ThisWorkbook.Path, for example, gives you the name of the folder containing ThisWorkbook. Look up workbook property "Name".
If the source workbooks always have the same names, you could hard code the names into the macro. I do not recommend this. Look up the function "Dir".
I hope the above has given you a start on breaking your total problem down into its components.
There are many different VBA tutorials available on the web. Try a few and pick one you like.
"Debug.Print xxx" outputs the value of xxx to the Immediate Window. This can be very helpful as you start. Try this as your first macro:
Option Explicit
Sub First()
Dim FilenameCrnt As String
Dim WbookCrnt As Workbook
Debug.Print ThisWorkbook.Name
Debug.Print ThisWorkbook.Path
FilenameCrnt = Dir$(ThisWorkbook.Path & "\*.*")
Do While FilenameCrnt <> ""
Debug.Print FilenameCrnt
If FilenameCrnt = ThisWorkbook.Name Then
With ThisWorkbook
Debug.Print " Used range: " & .Worksheets(1).UsedRange.Address
End With
Else
If LCase(Right(FilenameCrnt, 3)) = "xls" Or _
LCase(Right(FilenameCrnt, 4)) = "xlsm" Or _
LCase(Right(FilenameCrnt, 4)) = "xlsx" Then
WbookCrnt = Workbooks.Open(ThisWorkbook.Path & "\" & FilenameCrnt)
With WbookCrnt
Debug.Print " Used range: " & .Worksheets(1).UsedRange.Address
End With
WbookCrnt.Close
WbookCrnt = Nothing ' Free resource
End If
End If
FilenameCrnt = Dir$
Loop
End Sub
Best of luck
I have a macro that is on a server. I need to be able to run it from different workstations that connect to this server.
Currently I am doing:
Application.Run ("L:\database\lcmsmacro\macro1.xlsm!macro_name")
The error message I am getting is "The macro may not be available in this workbook #1004"
I have already made sure that my security settings are set on the lowest level.
How do I run a macro from another workbook which is hosted on a different server?
would using add-ins help me?
I think your syntax is missing the single quote characters:
Application.Run ("'L:\database\lcmsmacro\macro1.xlsm'!macro_name")
Then, if you needed to pass parameters to it the syntax would be like this:
Application.Run ("'L:\database\lcmsmacro\macro1.xlsm'!macro_name","param1","param2")
This error also shows up when there are duplicate macro names in the remote workbook, e.g. two macros named "macro_name". Took me a while to find out!
Generally in Names a single ‘ is required if you have a space or punctuation in a name so that Excel does not get confused thinking that the space is a deliberate separation, such as in separating arguments from a Method.
In some cases Excel will insist on them. Usually it does no harm to include them, even if they are not needed, for example when no spaces are present in names. Sometimes Excel will then take them out if they are not needed.
http://www.eileenslounge.com/viewtopic.php?f=27&t=25599
If the macro you need to find relative macro path by using workbook path from which you run macro and you need to run several macros from the array list, the code below will help:
Dim relativePath As String, programFileName As String
Dim selectedProgramsFiles() As String, programsArrayLastIndex As Byte, I As Byte
For I = 0 To programsArrayLastIndex 'Loop through all selected programs
programFileName = selectedProgramsFiles(I)
relativePath = ThisWorkbook.Path & "\" & programFileName
Workbooks.Open Filename:=relativePath
Application.Run ("'" & relativePath & "'!ModuleName.Main")
Workbooks(programFileName).Activate
ActiveWorkbook.Close SaveChanges:=False
Next I 'For I = 0 To programsArrayLastIndex 'Loop through all selected program