I'm trying to find a way to use an Excel sheetname as a variable in a macro that I've written. Every month I deal with a workbook that is sent to me with 2 sheets. Part of the macro uses the 'Open File' interface to navigate to the folder and open the file.
The first sheet in the file is called 'Report', which is static. All I do with that is delete it (because I don't need it).
The second sheet could be called anything and that's the sheet upon which I need to run the macro. Is there a way to say:
shtName = %whatever_the_sheetname_is_called%
and then use the 'shtName' variable throughout the macro? I suppose getting this new filename as a variable would help as well.
in a Visual Basic Macro you would use
pName = ActiveWorkbook.Path ' the path of the currently active file
wbName = ActiveWorkbook.Name ' the file name of the currently active file
shtName = ActiveSheet.Name ' the name of the currently selected worksheet
The first sheet in a workbook can be referenced by
ActiveWorkbook.Worksheets(1)
so after deleting the [Report] tab you would use
ActiveWorkbook.Worksheets("Report").Delete
shtName = ActiveWorkbook.Worksheets(1).Name
to "work on that sheet later on" you can create a range object like
Dim MySheet as Range
MySheet = ActiveWorkbook.Worksheets(shtName).[A1]
and continue working on MySheet(rowNum, colNum) etc. ...
shortcut creation of a range object without defining shtName:
Dim MySheet as Range
MySheet = ActiveWorkbook.Worksheets(1).[A1]
Related
I use this piece of code:
Application.Workbooks(V_WBNameOutPut).Activate
to activate a particular excel file, I notice that this method goes in error if the "File name extension" (in the View tab of the Folder Menu) is flagged.
In order to be independent of this, what modification should I do/include to the code or what alternative method should I use?
This answer is based on the comment
I interchange many times during the macro run between 2 workbooks, input and output
excel files, and I need to activate the V_WBNameOutPut, to paste and elaborate, and > this is done multiple times during the run. From the input file, I create the > V_WBNameOutPut file.
As #brax said - capture the workbook when it's opened and you don't have to worry about the extension after that.
Sub Test()
'Open the first workbook and store reference to it.
Dim wrkBk1 As Workbook
Set wrkBk1 = Workbooks.Open("H:\Darren Bartrup-Cook\Test 1.xlsx")
'Open the second workbook and store reference to it.
Dim wrkBk2 As Workbook
Set wrkBk2 = Workbooks.Open("H:\Darren Bartrup-Cook\Test 2.xlsx")
'Copy/paste from wrkbk1 to wrkbk2.
wrkBk1.Worksheets("Sheet1").Range("A1").Copy Destination:=wrkBk2.Worksheets("Sheet1").Range("A4")
'Create a new sheet in wrkbk2.
Dim NewWrkSht As Worksheet
Set NewWrkSht = wrkBk2.Worksheets.Add
NewWrkSht.Name = "My New Sheet"
'Paste copy/paste values from wrkbk1 to wrkbk2.
wrkBk1.Worksheets("Sheet1").Range("A2").Copy
NewWrkSht.Range("A5").PasteSpecial Paste:=xlPasteValues
'Make A3 in wrkbk2 equal the value in wrkbk1 A3.
wrkBk2.Worksheets("Sheet1").Range("A3") = wrkBk1.Worksheets("Sheet1").Range("A3")
'Close the two workbooks.
wrkBk2.Close SaveChanges:=True
wrkBk1.Close SaveChanges:=False
End Sub
I want to create a macro where it will copy some data from one workbook (whose name stays always same - "SameNameWorkbook") and pastes that data in another open workbook whose name is changing everyday (because its name is a date). For example today my workbook which I want to paste the data in is called "11.06.2021".
What I did is I created a =today() formula in the J2 cell in the active workbook (different from the other 2 and named "CurrentWorkbook") and created a variable in VBA for the workbook with changing name:
`Second_workbook = Range("J2").Value`
When I want to have always a reference to the second workbook I wrote this:
`Windows("Second_workbook.xlsx").Activate`
`Range.("A1").Select`
`ActiveSheet.Paste`
Since Second_workbook is a variable linked to the =today() formula which is 11.06.2021 I thought that will put the date before .xlsx. However, this shows an error so my logic is wrong. Since I am more fond of Excel formulas I thought that this logic will work like the indirect function but obviously it doesn't.
So the end result which I want to have is following:
`Windows("11.06.2021.xlsx").Activate`
Tomorrow, then I want to have the following:
`Windows(12.06.2021.xlsx").Activate`
... and so on without me manually changing the name workbook in the macro everyday while I keep all 3 workbooks open of course.
Could you please help me with this issue? I would really appreciate your help.
Date Formatting
You have to format your date:
Format(Date, "dd.mm.yyyy") & ".xlsx"
Format(Range("J2").Value, "dd.mm.yyyy") & ".xlsx"
Date is the equivalent of Excel's TODAY in VBA.
Here's a common scenario (adjust the worksheet names and the ranges):
Option Explicit
Sub CopyToToday()
Dim swb As Workbook: Set swb = ThisWorkbook ' workbook containing this code
' Attempt to create a reference to the Destination Workbook.
Dim dName As String: dName = Format(Date, "dd.mm.yyyy") & ".xlsx"
On Error Resume Next
Dim dwb As Workbook: Set dwb = Workbooks(dName)
On Error GoTo 0
If dwb Is Nothing Then
MsgBox "Could not create a reference to today's workbook.", _
vbCritical, "Workbook not open"
Exit Sub
End If
' Copy a range from Source Worksheet to Destination Worksheet.
swb.Worksheets("Sheet1").Range("A1:F10").Copy
dwb.Worksheets("Sheet1").Range("A1").PasteSpecial
Application.CutCopyMode = False
'dwb.Save
End Sub
"Second_workbook.xlsx" is a string and will be interpreted as a string, ignoring any variables with the same name.
Variables are written out without quotes, and strings of text have the quotes. Everything within quotes (green text) is taken as a string of text. To combine strings and variables we use the & operand like so:
"string" & variable & "string"
So what you are looking for should be:
Windows(Second_workbook & ".xlsx").Activate
You might want to save the workbook as a variable object instead, to refer to it easier:
Dim wb As Workbook
Set wb = Workbooks(Range("J2") & ".xlsx")
Or if you are using the Second_workbook variable anyway, you can set it like:
Set wb = Workbooks(Second_workbook & ".xlsx")
Remember that this range, just as in your example will be interpreted as ActiveWorkbook.ActiveSheet.Range("J").value unless you specify it. Make sure that this won't cuase problems.
To activate a cell in this workbook, you can use wb.Worksheets(1).Range("A1").Select, for example.
So I am trying to write a Macro for Excel, that adds 2 worksheets from an excel file to a new one.
Therefore, I try this:
Sub addfile()
Dim sheet1 As Worksheet
Dim sheet2 As Worksheet
Set sheet1 = Sheets.Add(Type:="C:\Users\Helge\AppData\Roaming\Microsoft\Templates\page1.xltx")
Set sheet2 = Sheets.Add(Type:="C:\Users\Helge\AppData\Roaming\Microsoft\Templates\page2.xltx")
End Sub
When I test it, it imports the first page, but the 2nd page gives me a Runtime error 1004.
Why does this happen?
And is there another way to get 2 sheets from one excel file to another via vba?
Much to my surprise this version of your code actually worked for me.
Sub addfile()
Dim Sheet1 As Worksheet
Dim Sheet2 As Worksheet
Set Sheet1 = Sheets.Add(Type:=Environ("Userprofile") & "\OneDrive\Desktop\Template1.xltx")
Set Sheet2 = Sheets.Add(Type:=Environ("Userprofile") & "\OneDrive\Desktop\Book2.xlsx")
Debug.Print Sheet1.Name, Sheet2.Name
End Sub
The reason for my surprise is that Sheet1 and Sheet2 are the default CodeName for the first and second worksheets in any workbook. Therefore there is a conflict of naming between the Sheet1 in the workbook and the Sheet1 you declare which should come to the surface not later than Debug.Print Sheet1.Name. In fact, it may have. I didn't check which name was printed. But the code didn't crash. Since it crashes on your computer, perhaps you have an older version of Excel. Try to stay clear of variable names that Excel also uses. Or there is something wrong with the path & file name, which is hard to tell in that syntax and therefore kept me fooled for quite some time too.
In fact, I discovered the above only after finding out that my Desktop was on OneDrive and not before I had written the function below which is designed to avoid the use of Sheets.Add. It also has some extras such as being able to specify the sheet to take from the template (you could have one template with 2 or more sheets). You can specify an index number or a sheet name. And the function will give a name to the copy, too, if you specify one.
Private Function AddWorksheet(ByVal Template As String, _
TabId As Variant, _
Optional ByVal TabName As String) As Worksheet
Dim Wb As Workbook
Dim Path As String
Dim FileName As String
Set Wb = ThisWorkbook ' change to suit
' make sure the path ends on "\"
Path = "C:\Users\Helge\AppData\Roaming\Microsoft\Templates\"
With Workbooks.Open(Path & Template)
.Sheets(TabId).Copy After:=Wb.Sheets(Wb.Sheets.Count)
.Close
End With
Set AddWorksheet = ActiveSheet
If Len(TabName) Then ActiveSheet.Name = TabName
End Function
You can call the function from a sub routine like this:-
Sub AddWorksheets()
Dim Tab1 As Worksheet
Dim Tab2 As Worksheet
Application.ScreenUpdating = False
Set Tab1 = AddWorksheet("Page1.xltx", 1, "New Tab")
Set Tab2 = AddWorksheet("Page2.xltx", "Sheet1", "Another new Tab")
Application.ScreenUpdating = True
End Sub
Please observe the difference between the two function calls.
I am new to VBA and got that problem which I don't know how to fix.
I have a workbook with some sheets and I create a new workbook for each sheet in that first one with the name of the sheets. That works...
Now, I declare a variable of type string which defines the path to one of these new workbooks.
After defining that string I use that in the open function and when i change something in that workbook i opened, it also changes it in the worksheet where i get the name from(e.g. the name of the worksheet, like below)
Public Sub ProcessWorksheet(ByVal Worksheet As Excel.Worksheet)
Dim fileName As String
Dim currProFile as Workbook
Dim currProSheet as Worksheet
fileName ="some path" & "\" & worksheet.name & ".xlsx"
Set currProFile = Workbooks.Open(fileName)
Set currProSheet = currProFile.ActiveSheet
currProSheet.name = "DATA"
End Sub
So I think there is a reference to that worksheet i just use for the name cause of that worksheet.name.
My question is: How can I get the name without a reference to the worksheet.
I hope it is all cleal and thanks for help!
Well, I started all over again and just used the most important code and now it works. I don't know why but it does. So I think it was just an error by Excel itself.
Anyways thank you braX for editing advice
I have a workbook containing one worksheet ("DB Output" or Sheet 34) which I would like to copy to several (around 45) files in within the same folder.
None of the target files have an existing sheet named "DB Output" - the objective is to find a way to insert a copy of this sheet, forumlas and all, into each one.
The range of cells on that sheet that needs to be copied to a sheet of the same name in each book is A1:PE5
The sheet contains references to cells in the book it is currently in, however as the files which I am seeking to copy the worksheet to all share the same template, I want the references to be to the local file, not the original one.
I've tried looking at RDBMerge, however it seems that is for merging sheets, and while I do want to do that, it will not help me do it multiple times quickly.
Likewise I have looked on SO for similar situations, this is the closest, however my attempts to adapt that code have failed as I only have a single workskeet. Never the less, as it is always useful to inlcude what you have already tried, here is my existing attempt:
Option Explicit
Public Sub splitsheets()
Dim srcwb As Workbook, trgwb As Workbook
Dim ws As Worksheet, t1ws As Worksheet
Dim rng1 As Range
Dim trgnm As String
Dim fpath As String
Application.ScreenUpdating = False
'--> Set this to the location of the target workbooks
fpath = "C:/file/path/"
Set srcwb = ThisWorkbook
For Each ws In srcwb.Worksheets
trgnm = ws.Name
'--> Change A1:B3 to the range to be copied to inside page
Set rng1 = srcwb.Sheets(trgnm).Range("A1:PE5")
Set trgwb = Workbooks.Open(fpath & trgnm & ".xlsm")
With trgwb
Set t1ws = .Sheets("DB Output")
End With
'--> Change A1:B3 to the range where you want to paste
rng1.Copy t1ws.Range("A1:PE5")
trgwb.Close True
Next
Application.ScreenUpdating = True
End Sub
However this starts with the first sheet in the workbook that contains DB Output (the sheet to be copied) and gives an error that "NameOfSheet1.xlsm" does not exist in that directory (which it does not).
Any help is much appreciated.
This should copy from the active workbook to all files in a directory. If you need help modifying it to fit your specific use let me know!
Edit: fixed code to only copy A1:PE5 and save each workbook.
Sub Example()
Dim path As String
Dim file As String
Dim wkbk As Workbook
path = "C:\Test\"
file = Dir(path)
Application.DisplayAlerts = False
Do While Not file = ""
Workbooks.Open (path & file)
Set wkbk = ActiveWorkbook
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Name = "DB Output"
ThisWorkbook.Sheets("DB Output").Range("A1:PE5").Copy Destination:=wkbk.Sheets("DB Output").Range("A1")
wkbk.Save
wkbk.Close
file = Dir
Loop
Application.DisplayAlerts = True
End Sub
Please note that I did not add error handling so this could break if the active workbook is included in the directory you are trying to copy or if a sheet with the same name already exists in the workbook. If this is an issue let me know and I will add error handling.