Vba code stops after workbook open. No errors - vba

I have some code that is meant to open an xlsm workbook, copy some data from it and paste it in the workbook with the code. Both workbooks are password protected and the code is password protected. I have some code that is setup to run before save, open and close which locks the workbook.
So the problem is that the code stops with no errors after the workbook is opened by vba as seen below. I thought it has something to do with the shift key, a problem I have seen all over the net with the open method but I altered the code to fix that and the problem was still there. I then tried removing the code for the on open in the workbook being opened and it worked. Why is this? I have run code just like this before with workbooks that have code on open and it worked just fine.
I am using Excel 2013.
Sub User_Update()
Application.ScreenUpdating = False
Dim strCurrentProgram As String
Dim MainProgramName As String
Dim strLocation As String
strLocation = "X:\Produktionsmesstechnik\Gehaeuse_Freigabe\"
strCurrentProgram = Dir(strLocation & "*.xlsm")
Do While strCurrentProgram <> ""
If InStr(strCurrentProgram, "Gehäuse Freigabe Program Ver") = 1 Then
If MainProgramName = "" Then
MainProgramName = strCurrentProgram
ElseIf CInt(Mid(MainProgramName, 29, 3)) < CInt(Mid(strCurrentProgram, 29, 3)) Then
MainProgramName = strCurrentProgram
End If
End If
strCurrentProgram = Dir
Loop
Workbooks.Open Filename:=strLocation & MainProgramName <<<< CODE STOPS HERE
ActiveWorkbook.Sheets("Users").Range(Cells(4, 1), Cells(100, 11)).Copy
Call UserPassword_Unlock
ThisWorkbook.Sheets("Users").Range("A4").Paste
ThisWorkbook.Save
Workbooks(MainProgramName).Close
Call UserPassword_Lock
End Sub

I can see a couple of things wrong with your code aside from the code stopping.
The code may be stopping due to code in the other workbook firing when it opens, so that needs to be stopped.
The other problems I see are that you're not referencing the newly opened workbook with a variable, instead using ActiveWorkbook which may not always be correct.
The line where you're copy the range is using Users as the range reference, but the cell references are using the currently active sheet.
After your do loop I'd add this code:
Dim wrkBk As Workbook
Application.EnableEvents = False
Set wrkBk = Workbooks.Open(strLocation & MainProgramName)
Call UserPassword_Unlock
With wrkBk.Worksheets("Users")
.Range(.Cells(4, 1), .Cells(100, 11)).Copy _
Destination:=ThisWorkbook.Worksheets("Users").Range("A4")
End With
ThisWorkbook.Save
wrkBk.Close SaveChanges:=False
Call UserPassword_Lock
Application.EnableEvents = True
Note I use wrkBk to reference the newly opened workbook. The Copy and Paste are shortened to a single line with each cell and range reference fully qualified using With wrkbk.Worksheets("Users").
Application.EnableEvents = False should stop any code firing when the workbook is opened.

But even Darren Bartrup-Cook's otherwise fine answer won't suffice if the Shift key is involved ! Vestiges of a bug in XL from 2005! Using the Shift key in a keystroke combination to run a macro will cause execution to halt after the the target workbook opens. For example, CTRL + SHIFT + q to run the macro won't work; CTRL + q will.

Related

excel Method 'open' of object 'workbooks' failed error when opening a read only workbook

I have code that should open open a handfull of workbooks, pull key info and close them. i can see the workbook loading but then when it is about to open i get the runtime error 1004 that says
Method 'open' of object 'workbooks' failed
My code is as follows and when i debug it takes me to the 2nd line under the do while statement:
Sub OEEsummmary()
Dim Gcell As Range
Dim MySheet As Worksheet
Dim Txt$, MyPath$, MyWB$
Dim myValue As Integer
Dim x As Long
Dim v As Variant, r As Range, rWhere As Range
MyPath = "L:\Manufacturing Engineering\Samuel Hatcher\"
x = 2
Set MySheet = ActiveSheet
Application.ScreenUpdating = False
Do While MySheet.Range("A" & x).Value <> ""
MyWB = MySheet.Range("A" & x).Text
Workbooks.Open Filename:=MyPath & MyWB, ReadOnly:=True, IgnoreReadOnlyRecommended:=True
Set Gcell = ActiveSheet.Range("E21")
With MySheet.Range("A" & x)
.Offset(0, 7).Value = Gcell.Value
End With
ActiveWorkbook.Close savechanges:=False
x = x + 1
Loop
End Sub
I tried to change the different defined variable to variant as per instructions of other people who had the same issue but nothing worked. Any help is greatly appreciated thanks!
update* I moved the two file names that were an issue to the bottom of the list and every other file name opened and copied the info perfectly but when the loop got to the last two files it gives me that error. all of the files are manipulated copies of the bottom 2 so i dont see why it doesnt work
update2* it seems as though the only workbooks that give the error and wont load are the ones open on another computer in the network, when this program is run all the workbooks will be open on other computers
it turns out a few of the files were corrupted so when the code encountered this it didnt work. the solution to this problem was to close the corrupted workbook then when I reopened it I clicked the arrow next to open and selected "open and repair" then saved a new copy of the file and the code ran smoothly

Macro stops after the first row , automation error

I was writing a macro and when I run the program, it runs fine when reading the first row but when it loops around and does the second row, I get an error, saids automation problem and the macro quits. I was wondering what's going on that it works fine for the first loop but not the second.
Basically, what I want the macro to do it read rows 8 - 25, if the cell has a date in cell (i) (i being 8, 9, 10, etc..), column B then copy row and paste it to another workbook.
Any body have any ideas? thanks! :)
Sub Update()
Dim Request As Workbook
Dim blank As Worksheet
Dim oakfield As Workbook
Set Request = Workbooks("Request_Microbiological_Analysis(blank).xlsm")
Set blank = Request.Worksheets("blank")
Set oakfield = Workbooks.Open("O:\_Public\Quality_Oakfield.xlsm")
With ThisWorkbook
Dim i As Long
For i = 8 To 25
If IsDate(Cells(i, 2)) Then
blank.Cells(i, "A").Resize(, 12).Copy
oakfield.Worksheets("Microlog").Range("A" & Rows.Count).End(xlUp).Offset(1).Select
Selection.PasteSpecial xlPasteValuesAndNumberFormats
ActiveWorkbook.Save
ActiveWorkbook.Close
ElseIf IsEmpty(Cells(i, 2)) Then
MsgBox "Oakfield Quality Updated"
End If
Next i
End With
MsgBox "Quality System Updated"
End Sub
Your issue here appears to be due to the fact that you close ActiveWorkbook in your loop, but then don't open it again. An automation error typically occurs when a workbook object is being referenced when it isn't open. You need to wait until after the loop to close your workbook.

Using Application.Run to open a workbook with protected worksheets and protected VBAProject

An employee at one of my company's local offices is working on a macro in Sheet1 of a workbook that would run a macro in another workbook using Application.Run:
Private Sub CommandButton1_Click()
Wfile = Range("B2").Value
Wpath = Range("B3").Value
Workbooks.Open Wpath + "/" + Wfile
Application.Run Wfile & "!copy_rates_macro"
End Sub
The workbook that he is trying to open/use is protected in every way possible (all of its sheets are protected and its VBAProject is protected as well.
When the macro is run, the 1004 run-time error message window pops up saying "Cannot rund the macro 'Name.xlsm!copy_rates_macro'. The macro may not be available in this workbook or all macros may be disabled.'
I did a lot of research and I thought the putting the following in the protected file would work:
Private Sub Workbook_Open()
' Dim wSheet As Worksheet
' For Each wSheet In Worksheets
' wSheet.Protect Password:="pw", UserInterFaceOnly:=True
' Next wSheet
Application.EnableEvents = False
End Sub
Note that the parts commented out above are my additions to code that was already there and must remain there. Also, "pw" is the password for every worksheet and the VBAProject.
This code didn't make a difference (it wasn't commented out when I ran it), and I imagine it has something to do with the VBAProject being protected.
Is this request even possible, or is it a lost cause? My boss doesn't want the password to the protected workbook to be released but I can't see a way around it.
Thanks for any help.
You shouldn't have to unprotect a project to run code in it (that would make it pretty worthless), but I can see a couple of possible issues in your code. First you use "/" at the end of the path rather than "\" and second, if the workbook name contains spaces you need to enclose it in single quotes:
Workbooks.Open Wpath + "\" + Wfile
Application.Run "'" & Wfile & "'!copy_rates_macro"
If that still won't run, there are a few possible pitfalls:
1. The macro is in a module of the same name, or in an object module, such as a worksheet or ThisWorkbook, in which case you need to prefix the macro name with the code name of the object.
2. Automation Security may be disabling macros in the opened workbook. To work around that, try adding:
Application.AutomationSecurity = msoAutomationSecurityLow
before opening the workbook. Ideally, you should store the current value and reset that at the end.

Macro that runs a Macro that opens files and save them as value - Runtime Error 1004

I keep getting this 1004 runtime error. I have slimmed my programing down some so it’s not so Programception. I think it may have to do with using Excel 2010 to save .xls files. Not sure.
When Auto_Root.xls opens it runs Sub auto_open() which opens
Panel.xls
Panel opens and runs Sub Update() which sequentially opens 7 files
in different directories all called Auto_Update.xls
Auto_Update.xsl opens and runs Sub Flat which each open a number of
files sequentially and saves a flat copy of themselves in another
directory.
I have opened each of the 7 Auto_Update.xls files and have run them independently and they run with no errors. When I run them all from Auto_Root I get a runtime error 1004. And CurrentWB.Save is highlighted on one of the files. I even replaced CurrentWB.Save as CurrentWB.SaveAs Filename:=TargetFile, FileFormat:=xlNormal and recieved the same runtime error.
Attached is the code I have.
AutoRoot.xls!Auto Update
Sub auto_open()
Application.CutCopyMode = False
Dim PanelFilePath As String
Dim PanelFileName As String
Dim PanelLocation As String
Dim PanelWB As Workbook
PanelFilePath = "D:\umc\UMC Production Files\Automation Files\"
PanelFileName = "Panel.xls"
PanelLocation = PanelFilePath & Dir$(PanelFilePath & PanelFileName)
Set PanelWB = Workbooks.Open(Filename:=PanelLocation, UpdateLinks:=3)
PanelWB.RunAutoMacros Which:=xlAutoOpen
Application.Run "Panel.xls!Update"
PanelWB.Close
Call Shell("D:\umc\UMC Production Files\Automation Files\Auto.bat", vbNormalFocus)
Application.Quit
End Sub
Panel.xls!Update
Sub Update()
Dim RowNumber As Long
Dim AutoUpdateTargetFile As String
Dim AutoUpdateWB As Workbook
For RowNumber = 1 To (Range("AutoUpdate.File").Rows.Count - 1)
If (Range("AutoUpdate.File").Rows(RowNumber) <> "") Then
AutoUpdateTargetFile = Range("Sys.Path") & Range("Client.Path").Rows(RowNumber) & Range("AutoUpdate.Path ").Rows(RowNumber) & Range("AutoUpdate.File").Rows(RowNumber)
Set AutoUpdateWB = Workbooks.Open(Filename:=AutoUpdateTargetFile, UpdateLinks:=3)
AutoUpdateWB.RunAutoMacros Which:=xlAutoOpen
Application.Run "Auto_Update.xls!Flat"
AutoUpdateWB.Close
End If
Next RowNumber
End Sub
AutoUpdate.xls!Flat
Sub Flat()
Dim RowNumber As Long 'Long Stores Variable
Dim SheetNumber As Long
Dim TargetFile As String 'String Stores File Path
Dim BackupFile As String
Dim CurrentWB As Workbook 'Workbook Stores Workbook
For RowNumber = 1 To (Range("File").Rows.Count - 1)
'Loops through each file in the list and assigns a workbook variable.
If (Range("File").Rows(RowNumber) <> "") Then
TargetFile = Range("Sys.Path") & Range("Path").Rows(RowNumber) & Range("File").Rows(RowNumber) 'Target File Path
BackupFile = Range("Report.Path") & Range("Path").Rows(RowNumber) & Range("SubFolder") & Range("File").Rows(RowNumber) 'Backup File Path
Set CurrentWB = Workbooks.Open(Filename:=TargetFile, UpdateLinks:=3) 'Sets CurrentWB = to that long name. This becomes the name of the workbook.
CurrentWB.RunAutoMacros Which:=xlAutoOpen 'Enables Macros in Workbook
CurrentWB.SaveAs Filename:=TargetFile, FileFormat:=56
For SheetNumber = 1 To Sheets.Count 'Counts Worksheets in Workbook
Sheets(SheetNumber).Select 'Selects All Worksheets in Workbook
If (Sheets(SheetNumber).Name <> "What If") Then
Sheets(SheetNumber).Unprotect ("UMC626") 'Unprotects Workbook
Cells.Select 'Selects Data in Workbook
Range("B2").Activate
With Sheets(SheetNumber).UsedRange
.Value = .Value
End With
Sheets(SheetNumber).Protect Password:="UMC626", DrawingObjects:=True, Contents:=True, Scenarios:=True 'Protects Workbook
End If
Next SheetNumber 'Runs Through Iteration
Sheets(1).Select
Range("A1").Select 'Saves each workbook at the top of the page
CurrentWB.SaveAs Filename:=BackupFile, FileFormat:=56, Password:="", WriteResPassword:="", _
ReadOnlyRecommended:=False, CreateBackup:=False 'Saves Workbook in Flatten File Location
CurrentWB.Close 'Closes Workbook
End If 'Ends Loop
Next RowNumber 'Selects Another Account
End Sub
What I have done so far.
Each Individual AutoUpdate file works when ran on its on.
If Application.Run"Auto_Update.xls!Flat" is removed from Panel.xls!Update it opens and closes all of the AutoUpdate.xls files with no error.
If I link Panel.xls!Update to only 3 of the 7 AutoUpdate files.... any 3. It runs with no errors.
I just can't seem to get it to run all 7 without saying Runtime Error 1004.
I found a microsoft work around code. Not sure how to implement it though.
Sub CopySheetTest()
Dim iTemp As Integer
Dim oBook As Workbook
Dim iCounter As Integer
' Create a new blank workbook:
iTemp = Application.SheetsInNewWorkbook
Application.SheetsInNewWorkbook = 1
Set oBook = Application.Workbooks.Add
Application.SheetsInNewWorkbook = iTemp
' Add a defined name to the workbook
' that RefersTo a range:
oBook.Names.Add Name:="tempRange", _
RefersTo:="=Sheet1!$A$1"
' Save the workbook:
oBook.SaveAs "c:\test2.xls"
' Copy the sheet in a loop. Eventually,
' you get error 1004: Copy Method of
' Worksheet class failed.
For iCounter = 1 To 275
oBook.Worksheets(1).Copy After:=oBook.Worksheets(1)
'Uncomment this code for the workaround:
'Save, close, and reopen after every 100 iterations:
If iCounter Mod 100 = 0 Then
oBook.Close SaveChanges:=True
Set oBook = Nothing
Set oBook = Application.Workbooks.Open("c:\test2.xls")
End If
Next
End Sub
http://support.microsoft.com/kb/210684/en-us
Based on the document from Microsoft linked below this is a known issue.
Copying worksheet programmatically causes run-time error 1004 in Excel
I'm not sure how many sheets this loop in Flat but it appears that is the issue. Specifically the quote:
This problem can occur when you give the workbook a defined name and then copy the worksheet several times without first saving and closing the workbook
Due to the levels that you have created using separate workbooks I would suggest starting with limiting the scope of your Update subroutine. There are many designs for something like that but I might start with passing an integer argument back and fourth between Auto Open and Update. That way you can close and reopen Panel.xls multiple times and start exactly where you left off.
Its not clear from your text, but is your procedure "Flat" inside the files you are opening and if so is it being called by the auto open macro?
It sounds like you want to only be running your macro from your original workbook, and not firing the ones in the auto open macro of the workbooks you open.
If this is indeed the case, I do something similar in one of my workbooks, where I have an "upgrade" wizard that fires when the work book is opened, however because I am upgrading, the other workbook I open, also has the upgrade wizard, and so that used to fire as well. I resolved this by opening the other workbook in a hidden instance of excel, and within my auto open macro, I have a line of code that queries the visible state of the workbook, and does not fire if it is hidden. So in the below code its the "And Me.Application.visible" that controls if the wizard is run
'Check if the ODS code is populated or default xxx, if so invoke the upgrade wizard
'but only if the application is visible
If (ActiveWorkbook.Names("Trust_ODS_Code").RefersToRange.Value = "xxx" _
Or Len(ActiveWorkbook.Names("Trust_ODS_Code").RefersToRange.Value) = 0) _
And Me.Application.visible = True Then
'run the upgrade wizard
frmCSCWizardv8.Show
End If
This requires that you open your workbooks in a separate excel instance. The below code is the snippet of code that does this, hope this is enopugh for you to get the idea
Dim lRet
Dim i As Integer, j As Integer
Dim FoundSheet As Boolean
'Because the wizard opens the old DCS in a hidden instance of Excel, it is vital that we close this if
'anything goes wrong, so belt and braces, close it every time the user presses the button
'Switch off the error handling and the display alerts to avoid any error messages if the old dcs has
'never been opened and the hidden instance does not exist
Application.DisplayAlerts = False
On Error Resume Next
book.Close SaveChanges:=False
app.Quit
Set app = Nothing
Application.DisplayAlerts = True
'set error handling
On Error GoTo Err_Clr
'populate the status bar
Application.StatusBar = "Attempting to open File"
'Default method Uses Excel Open Dialog To Show the Files
lRet = Application.GetOpenFilename("Excel files (*.xls;*.xlsx;*.xlsm;*.xlsb), *.xls;*.xlsx;*.xlsm;*.xlsb")
'If the user selects cancel update the status to tell them
If lRet = False Then
Me.lstOpenDCSStatus.AddItem "No file selected"
'if the user has selected a file try to open it
Else
'This next section of code creates a new instance of excel to open the selected file with, as this allows us to
'open it in the background
OldDCS = lRet
Application.StatusBar = "Attempting to open File - " & lRet
app.visible = False 'Visible is False by default, so this isn't necessary, but makes readability better
Set book = app.Workbooks.Add(lRet)
Application.StatusBar = "Opened File - " & lRet

Using Excel VBA, how do I keep my original code executing after a 'thisworkbook.close' event in a 2nd workbook?

In Excel 2007, I have a sheet with a list of other Excel documents, all of which have their own VBA. My code opens the first workbook on the list, lets its vba run, then when it has completed, marks it as complete, and opens the next workbook in the list.
All this works fine unless I let one of the other workboks close itself with 'thisworkbook.close'. This stops the VBA running in the original workbook, as well as itself. If I comment this line out, it all works, but I would rather keep just the master workbook and one sub workbook open at one time.
Also, it is unpractical in this case to move all the VBA to the master workbook.
The code before is a highly simplified version to show the issue:
Workbook1's code:
Sub RunReports()
Dim wkb1 As Workbook
Dim wks1 As Worksheet
Dim lngR As Long
Dim strReport As String
Set wkb1 = ThisWorkbook
Set wks1 = wkb1.Sheets(strDay)
For lngR = 4 To 1048576
strReport = wks1.Cells(lngR, 1).Value
'open the report. Its own VBA will take care of everything else
Workbooks.Open strReport
'mark the report as complete
wks1.Cells(lngR, 2).Value = "done"
Next lngR
End Sub
the code in the worksheets that are opened:
Private Sub Workbook_Open()
ThisWorkbook.Sheets("Sheet1").Cells(1, 1).Value = Now()
ThisWorkbook.Save
Application.Wait (Now() + TimeValue("00:00:05"))
ThisWorkbook.Close
End Sub
If I comment out 'thisworkbook.close', it will open them all, update the time they were opened, and save them. If not, it does everything up to the first 'thisworkbook.close', closes the first sub workbook, and stops all VBA execution.
Does anyone have any ideas how to keep the "master" workbook's vba code running after the "sub" workbook's code has finished, when the 'sub' workbook's code contains a 'thisworkbook.close' (edited to make the question clear)
Use standard COM ways of doing things. Take a reference to each workbook (not excel.application) using GetObject(filename). Do what you want then don't close it in sub book, but set the reference to nothing in your master (which happens when you do set exceldoc = nothing or reach an End Function/Sub). Don't do both as that's voodoo programming.