Activate different workbook to run macro - excel

I created a macro in my workbook using an active worksheet from another workbook. I would now like to run my macro, but use yet another different active workbook to get my data.
I have this line 20 times in my macro...
Windows("IFS_round_1").Activate
...so I do not want to change it (ex. IFS_round_2) each time I open a new workbook to run the macro. Is there something I can add so the macro just uses whichever active workbook I have open?
Thanks!

Create a variable to refer to the workbook. For example:
Sub Macro1()
Dim wb as Workbook
Set wb = ActiveWorkbook
wb.Activate
'DO CODE HERE
End Sub
Does this help?

I don't know if you are opening the other workbook programatically, but this solution works. basically you just save the handle to the other workbook as soon as you open it.
sother_filename = "IFS_round_1"
'saves the name of the current workbook
curr_workbook = ActiveWorkbook.Name
'opens the new workbook, this automatically returns the handle to the other
'workbook (if it opened it successfully)
other_workbook = OpenWorkbook(sother_filename)
But what fun is that? one more solution to automatically get the workbook name when there are only two workbooks open and then simply use that to call the other workbook
Function GetOtherWBName()
GetOtherWBName = ""
'if we dont have exactly two books open
'we don't know what to do, so just quit
If (Workbooks.Count) <> 2 Then
Exit Function
End If
curr_wb = ActiveWorkbook.Name
'if the active workbook has the same name as workbook 1
If (StrComp(curr_wb, Workbooks(1).Name) = 0) Then
'then the other workbook is workbook 2
GetOtherWBName = Workbooks(2).Name
Else
'then this is the other workbook
GetOtherWBName = Workbooks(1).Name
End If
End Function
So now in the workbook that has the macro make a button and assign a macro to it similar to this
Sub ButtonClick()
'first we save the current book, so we can call it easily later
curr_wb = ActiveWorkbook.Name
other_wb = GetOtherWBName()
If Len(other_wb) = 0 Then
MsgBox ("unable to get other wb")
Exit Sub
End If
'now to call the other workbook just use
Workbooks(other_wb).Activate
'all the rest of your code
End Sub

Related

Application.Workbooks(V_WBNameOutPut).Activate alternative

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

When looping through all open workbooks, code exits the loop after one workbook

I want to loop through all open Excel workbooks to identify which one on which to perform operations. Problem is, the code exits the for loop after the active workbook and returns "Nothing" as a result, regardless of how many workbooks I have open.
I need to run this routine weekly to transfer working hours from a downloaded Excel workbook into an alternate workbook. The name of the file changes every week, but always begins with "Timesheets"
I used this routine every week from January through April without any problems. I tried to use it today and this problem cropped up. I've used the routine on several different computers with different operating systems (Windows 7, Windows 10).
I've saved, closed, and reopened the workbook I want to activate to no avail. I don't want to have to change the code every week to access a specific workbook, but use the first 4 letters in the file name to identify the file on which to perform operations.
Sub cmdImportHours_Click()
Dim ThisWB As Workbook
Dim ImportWB As Workbook
Dim WB As Workbook
Dim msg1 As String
Dim msg As Variant
' more variables
msg1 = "Required file not found. Open the import file and try again."
Set ThisWB = ThisWorkbook
ThisWB.Worksheets("Hours").Activate
'The following loop exits after one iteration (the active workbook),
'regardless of how many workbooks are open
For Each WB In Workbooks
If Left(WB.Name, 4) = "Time" Then
WB.Activate
Exit For
End If
Next WB
If WB Is Nothing Then
msg = MsgBox(msg1, vbOKOnly)
Exit Sub
End If
'more code
End Sub
I expect the loop to look at the name of every open Excel workbook, but it exits the For Loop after looking at the active workbook only.
Your For Each over all workbooks directly returns a usable variable, which references the wanted workbook, so you may even use the variable "ImportWB" here. Exiting the loop by Exit For, if you found the desired item, is good practice.
I introduced two variables for worksheets to use them for copy operations.
Sub cmdImportHours_Click()
Dim ImportWB As Workbook
Dim SourceSheet As Worksheet, DestSheet As Worksheet
Dim msg1 As String
Dim msg As Variant
For Each ImportWB In Workbooks
If Left(ImportWB.Name, 4) = "Time" Then Exit For
Next ImportWB
If ImportWB Is Nothing Then
msg1 = "Required file not found. Open the import file and try again."
msg = MsgBox(msg1, vbCritical + vbOKOnly, "Workbook not open")
Exit Sub
End If
Set DestSheet = ThisWorkbook.Worksheets("Hours")
'DestSheet.Activate is typically not necessary
Set SourceSheet = ImportWB.Sheets(1)
DestSheet.Range("A2:B10").Value = SourceSheet.Range("A2:B10").Value
' more code
End Sub
As ThisWorkbook is always the same (the workbook with your VBA-code), it's not necessary to give it an extra variable, and I omitted it.
If you don't get your already opened workbook by above code, then it's either opened within a protected view ...
For i = 1 To Application.ProtectedViewWindows.Count
Debug.Print "Protected Workbook: " & _
Application.ProtectedViewWindows(i).Workbook.Name
Next i
... or within another Excel instance. In that case you may reference it by e. g.
Set ImportWB = GetObject("Path\Filename.xlsx")
See here for more examples on that.
That because Exit For, just comment that line. And don't use WB outside for each use other variable instead, in this code variable count used to count matching workbooks
Dim count As String
count = 0
For Each WB In Workbooks
If Left(WB.Name, 4) = "Time" Then
count = count + 1
WB.Activate
'Exit For
End If
Next WB
If count < 1 Then
msg = MsgBox(msg1, vbOKOnly)
Exit Sub
End If

Copy a sheet to a New workbook (of one sheet) without opening it

I would like to copy a sheet from ActiveWorkbook, to a New Created workbook.
The New created workbook, will contains the copied sheet ONLY.
I also don't want it to open while copiying the sheet. I want to copy the sheet to the new created workbook silently.
If I do something like the following, the new created book is with 3 sheets, not one only, and it's opening while copiying. and also it's asking me if i want to saved it with Macro, while I only want to copy the sheet1, so no need for any macro with it, How to fix that to fits my needs ?
ThisWorkbook.Sheets("Sheet1").Copy
ActiveWorkbook.SaveAs "C:\DestinationWb.xlsx", FileFormat:=51
The newly created workbook will have to be open - otherwise how would you save it? - but toggling Application.ScreenUpdating might facilitate the "silent" copy you're looking for. Toggling Application.DisplayAlerts will also suppress alerts as needed.
Application.ScreenUpdating = False
Application.DisplayAlerts = False
ThisWorkbook.Sheets("Sheet1").Copy
ActiveWorkbook.SaveAs FileName:="C:\DestinationWb.xlsx", FileFormat:=51
ActiveWorkbook.Close
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Hello, I just tried the code you provided, it still opens the book for about 1-2 seconds and close it. the user will clearly see that the book is opened. is there any other way, not forcely the sheet.copy or it's the only way to copy ? – JustGreat 50 mins ago
The only way I can think of in such a scenario is to do the following.
Logic:
Use the .SaveCopyAs method to save a copy of the existing workbook. You can read more about .SaveCopyAs HERE
Create another instance of Excel and Hide it
Open the copy in that instance
Delete all sheets except the one which you want.
Save and Close and finally quit the Excel instance.
Code:
Sub Sample()
Dim thisWb As Workbook
'~~> New File Name
Dim NewFile As String
NewFile = "C:\Users\routs\Desktop\New folder\DestinationWb.xlsx"
'~~> Sheets that you want to copy across
Dim SheetToCopy As String
SheetToCopy = "Sidd"
Set thisWb = ThisWorkbook
'~~> Save a copy of the current workbook to the new path
thisWb.SaveCopyAs NewFile
'~~> Create a new Excel instance and keep it hidden
Dim tmpExcelApp As Object
Dim ws As Object, thatWb As Object
Set tmpExcelApp = CreateObject("Excel.Application")
tmpExcelApp.Visible = False
'~~> Open the copy file in hidden instance
Set thatWb = tmpExcelApp.Workbooks.Open(NewFile)
'~~> Delete all sheets except the one we copied
tmpExcelApp.DisplayAlerts = False
For Each ws In thatWb.Worksheets
If ws.Name <> SheetToCopy Then ws.Delete
Next ws
tmpExcelApp.DisplayAlerts = True
'~~> Save and close
thatWb.Close (True)
'~~> Quit Excel Instance
tmpExcelApp.Quit
MsgBox "Done"
End Sub

Excel 2016 VBA workbook activates but then deactivates

I have a weird situation that I haven't been able to find the solution for.
I am dealing with large amounts of data on multiple workbooks that need to be opened (let's say 3 workbooks). I need a Userform to be able to interact with all 3 workbooks.
I have made a ComboBox able to do that by when the userform is initialized, it will add the names of the workbooks to the Combobox:
'* initialize the userform *'
Private Sub UserForm_Initialize()
Dim wb As Workbook
'* get the name of all the workbooks and add to the combobox '*
For Each wb In Application.Workbooks
Me.PrimaryBook_ComboBox.AddItem wb.name
Next wb
Me.PrimaryBook_ComboBox = ActiveWorkbook.name
End Sub
Upon a change, it will activate that workbook:
Private Sub PrimaryBook_ComboBox_Change()
Application.ScreenUpdating = True
Dim wb As Workbook
If Me.PrimaryBook_ComboBox <> "" Then
Set wb = Workbooks(Me.PrimaryBook_ComboBox.Text)
wb.Activate
End If
Application.ScreenUpdating = False
End Sub
(this userform has two refedits in it)
When I select another workbook in the combobox, it brings that workbook to the front as it should. But immediately as I click into one of my RefEdit boxes, it goes back to the original workbook opened first.
Here's another part I don't understand, when I load this in Excel 2010 it's flawless. I can select which workbook I want and click on the RefEdit and that workbook will remain activated.
Is there something I'm missing? Any tips and/or tricks that I did not think of?
Thank you
[delete , posted solution did not fix problem]

Is there a way to check for non-visible, open Excel Workbooks?

I have one open workbook with a button "SaveClose". I want the event on that button to close the entire Excel application if it is the last workbook opened. The thing is, there are possibility that there could be unknown personal.xlsb open or any other macro workbook open that is not visible.
I want to know if there is any other workable Excel workbook opened. Is there a check for a not visible workbook? If it is the last workbook, close Excel application, if not close active workbook, here's what I got:
Sub CloseForceSave()
'Save the workbook.
ThisWorkbook.Save
'If this is the only workbook opened in the current session, then...
If Workbooks.Count = 1 Then "or Workbooks.Count = 2" to account for personal.xlsb
'...quit Excel
Application.Quit
'Else...
Else
'...close the active workbook
ThisWorkbook.Close
End If
End Sub
When I do this I just ignore any hidden workbooks. If there is only one workbook with a visible window, I quit the application. I don't know of any better way of counting than a loop, but I've never had enough workbooks open for this to be a performance problem.
Function VisibleWorkbookCount() As Long
Dim wb As Workbook
Dim wd As Window
Dim lReturn As Long
For Each wb In Application.Workbooks
For Each wd In wb.Windows
If wd.Visible Then
lReturn = lReturn + 1
Exit For
End If
Next wd
Next wb
VisibleWorkbookCount = lReturn
End Function
if a workbook is not visible, it's usually a AddIn.
Try to check "Workbook.IsAddin Property"
see https://msdn.microsoft.com/de-de/library/office/ff838249.aspx

Resources