I'm experiencing a 1004 runtime error when saving a workbook (wbk_New) on which I copy-pasted a group of shapes from another workbook (wbk_Old). I should tell that a macro from wbk_Old is assigned to this group.
wbk_Old.Worksheets("DashBoard").Activate
ChartTop = ActiveSheet.Shapes("Group_VesselGraphics").Top
ChartLeft = ActiveSheet.Shapes("Group_VesselGraphics").Left
ActiveSheet.Shapes("Group_VesselGraphics").OnAction = ""
ActiveSheet.Shapes("Group_VesselGraphics").Copy
wbk_New.Worksheets("DashBoard").Activate
ActiveSheet.Shapes("Group_VesselGraphics").Delete
ActiveSheet.Paste
ActiveSheet.Shapes("Group_VesselGraphics").Top = ChartTop
ActiveSheet.Shapes("Group_VesselGraphics").Left = ChartLeft
ActiveSheet.Shapes("Group_VesselGraphics").OnAction = "'" & ActiveWorkbook.Name & "'!UpdateShipGraph"
wbk_Old.Close
wbk_New.SaveAs As path_Old
I can't figure out what is causing this error...Does anyone have already faced this issue ?
Thanks a ton for your help !
(I forgot to mention that a chart also belong to this group of shapes!)
Ok, I don't understand why but it seems that some links were still existing between "wbk_New" and "wbk_Old" although I broke all the links and updated the chart to refer to intrinsic data.
Hence, closing of "wbk_Old" couldn't be properly performed and wbk_New became corrupted, so that it was impossible to save it.
The only way I found to work around this issue is to save (on itself) wbk_New before closing wbk_Old and then to call an external process that replace wbk_Old by wbk_New, using a delay of 4s, and to close wbk_New and Old before the delay completed.
I have to admit that this is an ugly solution, if someone knows a better way it would be nice to share it!
Here below is the code of my solution, where BatchCmd creates a batch file of a command and shell it:
{code above}
wbk_New.Save
cmd = "ping -n 4 127.0.0.1 >nul" + vbCrLf
cmd = cmd + "move /Y " & path_New & " " & path_Old
Call BatchCmd(cmd, status:=vbHide)
wbk_Old.Close
wbk_New.Close
Related
I'm trying to cycle through several url's to download the pdf to a local folder.
An example of the url is https://find-energy-certificate.service.gov.uk/energy-certificate/8309-9619-9729-7796-8423?print=true
This is the vb I've written so far.
Dim sveloc As String
Dim svenme As String
Dim url As String
sveloc = Application.ActiveWorkbook.Path & "\Saved EPCs"
i = 7
Do Until sh01.Cells(i, 27) = "" 'all cells in the list are populated with no gaps
url = sh01.Cells(i, 27)
svenme = sh01.Cells(i, 2)
sveloc = sveloc & "\" & svenme & ".pdf"
ThisWorkbook.FollowHyperlink (url)
'code to open and save the pdf goes here
i = i + 1
Loop
Any help gratefully received as I'm really stumped on this one.
TIA.
Inspired by KJ's answer, without error checking etc. Just wanted to illustrate how you'd use shell to automate the entire process.
sveloc = Application.ActiveWorkbook.Path & "\Saved EPCs"
edgePath = Environ$("PROGRAMFILES(X86)") & "\Microsoft\Edge\Application\msedge.exe"
With CreateObject("WScript.Shell")
i = 7
Do Until Len(sh01.Cells(i, 27)) = 0 'all cells in the list are populated with no gaps
On Error Resume Next
.Run """" & edgePath & """ --profile-directory=Default --headless -print-to-pdf=""" & sveloc & "\" & sh01.Cells(i, 2) & ".pdf" & """ """ & sh01.Cells(i, 27) & """", 1, True
On Error GoTo 0
i = i + 1
Loop
End With
No need for VBA but you can use that to alter the variables so using your example from Windows we can run the build pdf at html runtime via Edge:-
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --profile-directory=Default --headless -print-to-pdf=C:\Users\WDAGUtilityAccount\Desktop\8309-9619-9729-7796-8423.pdf "https://find-energy-certificate.service.gov.uk/energy-certificate/8309-9619-9729-7796-8423?print=true"
and as if by magic the file is in less than a second on my desktop
There is no online pdf it is built by the browser. So it is essential to use the browser. You can remove the print header/footer with one extra switch, but cannot change orientation it will be A4 portrait in UK device.
-print-to-pdf-no-header see currently https://source.chromium.org/chromium/chromium/src/+/main:headless/app/headless_shell_switches.cc;l=60
one other switch may be of value if you only want smaller untagged files
-disable-pdf-tagging see https://source.chromium.org/chromium/chromium/src/+/main:headless/app/headless_shell_switches.cc;l=64
If you try to download without browser printing you will just get the raw HTML as needed for web page printing, thus calling browser remote print as above, will generate the desired "designed for the web" graphics copy.
curl -o test.htm https://find-energy-certificate.service.gov.uk/energy-certificate/8309-9619-9729-7796-8423?print=true
In comments the question was raised how to adapt this approach for change of browser and keeping call simple so I suggest use a cmd or bat file to make that part easier. Thus from vba call something like
Batchfile 8309-9619-9729-7796-8423
#echo off
set "browser=C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
set "filedir=C:\Users\WDAGUtilityAccount\Desktop"
set "urlpath=https://find-energy-certificate.service.gov.uk/energy-certificate"
"%browser%" --profile-directory=Default --headless --print-to-pdf="%filedir%\%~1.pdf" -print-to-pdf-no-header "%urlpath%/%~1?print=true"
However, beware calling pdf generations too fast, add a small wait between calls, even on multithreaded CPU writing PDF's at same time often leads to disasters, due to graphics resource conflicts.
Currently I have a document template with macros endabled .dotm. The macro has a commandbutton in there that triggers the SaveAs2 object twice formatted as below.
Public Sub FileSaveAs()
Dim dlg As Dialog
Dim strSaveFolder
strSaveFolder = Application.Options.DefaultFilePath(wdDocumentsPath)
Application.Options.DefaultFilePath(wdDocumentsPath) = ActiveDocument.AttachedTemplate.Path
ActiveDocument.SaveAs2 (ActiveDocument.AttachedTemplate.Path & " UsersName" & " FORM234" & Format(Now(), "DD-MMM-YYYY hh mm ss AMPM") & ".docm")
End
Second Save as
Public Sub SuperSave()
Dim dlg As Dialog
Dim strSaveFolder
strSaveFolder = "I:\Form Storage\CoCopy\"
ActiveDocument.SaveAs2 (strSaveFolder & "UserName" & "Form234" & Format(Now(), "DD-MMM-YYYY hh mm ss AMPM") & ".docm")
End Sub
Now here is the interesting part that has me stumped now for about a week now. This code works but only on some computers. Older models it doesn't work on for some reason. It doesn't matter Windows 10 or Windows 7 or Version of Office itself. It doesn't work on computers that are older in models like a HP EliteDesk 1 or HP EliteDesk 2. The 1 won't work but 2 will.
I have never heard of the vba macro being affected by the model of the computer version of OS yes version of Word ofcourse but never version of model. I have googled left and right and went to documentation from 2010 (including microsoft's killing activex issue of 2014 which I already ruled out)
This is how blank I mean doesn't even open the white page underneath.
Any ideas? Or have you heard of some computer models not running vba code but having the same OS and same version of Office?
Justin, I figured it out by chance were you trying to save a dotm as a docm. If the macro tries to save the dotm as a docm the formatting for the data is two separate instances. I followed through with this and noticed it in a test I ran on the document when right clicked and opened and got the same result try saving the template as a docm document instead this should resolve your issue.
Cindy, Justin is right it does yield a proper path and handles correctly in the VBA console without the slash. In the first sub he seems to only be after the path for the folder and is saving on the next parent folder outside of the folder containing the template macro. I have seen this work elsewhere why it is not working on specific models has me at a loss.
The second seems to target the location more specifically than the second which makes since if the folder is targeting a co-worker. I am currently trying to recreate the issue but having no luck your code works perfectly on my two systems I have running, both are rather new.
Try changing the wdsaveformat to match an extension type the formatting might be handled differently on newer models (unlikely but worth a shot)
Or rewrite the vba and document on the older afflicted models to see if they handle the setup and formatting differently
If Excel_Default_Path is set to C:\ProjectOutput the following code works perfectly. But if Excel_Default_Path is set to C:\Users\Me\ProjectOutput it fails with a 1004 error. Also, the appExcel object has no problem at all reading from that same directory in either case.
The DefaultOutputFilename is set to AA1FS-7_VE8GUS_ED.xls and fmt is getting the correct type. Just putting it into the User directory is a problem though.
A little more info. If I quit out of the VB app and select the open Excel app. I can directly save the modified workbook to C:\Users\Me\ProjectOutput with no problem at all.
Also, this error occurs on my machine, as well as another machine. The other machine Excel_Default_Path is set to C:\Users\JSS\ProjectOutput
Dim fmt As Excel.XlFileFormat = GetExcelFileFormatForExtension(fi)
appExcel.ActiveWorkbook.SaveAs(CStr(Excel_Default_Path & "\" & DefaultOutputFileName), fmt)
I have solved the problem. The Excel_Default_Path actually had a trailing "\" at the end. So that caused the 1004 error. Removing the \ from the variable fixed it.
I'm getting a persistent error:
The element cannot be found in a collection.
This error happens when you try to retrieve an element from a collection on a container during execution of the package and the element is not there.
I've checked, double and triple-checked my variable listings in the Read-Only and Read-Write variables in my Script task.
I've debugged it to death and gotten input from another programmer here who couldn't spot the issue either.
I've also researched to no end.
Does anyone see anything wrong with my code?
Script Task code:
Public Sub Main()
Dts.Variables("User::strMailBody").Value = "Thank you for submission. For your convenience, we are including the last four of the HICN# and the Name on the application(s) we have received* from you." _
& vbNewLine & vbNewLine & "Here are the following: " & vbNewLine & vbNewLine
Dts.Variables("User::strMailBody").Value = Dts.Variables("User::strMailbody").Value.ToString() & vbNewLine & Dts.Variables("User::strListing").Value.ToString()
Dts.Variables("User::strMailBody").Value = Dts.Variables("User::strMailBody").Value.ToString() & vbNewLine & vbNewLine & Dts.Variables("User::strFooter").Value.ToString()
If Left(Dts.Variables("User::strAgentID").Value, 2) = "TX" Then
Dts.Variables("User::strSubject").Value = "ACME Health Plans Confirmation: Total "
Else
Dts.Variables("User::strSubject").Value = "ACME2 Baptist Health Plans Confirmation: Total "
End If
Dts.Variables("User::strSubject").Value = Dts.Variables("User::strSubject").Value.ToString() & Dts.Variables("User::lngCountAgent").Value.ToString() & " " & "[RESTRICTED: CONFIDENTIAL]"
Dts.Variables("User::DateSent").Value = Now()
Dts.Variables("User::UserSent").Value = "SSIS"
Dts.TaskResult = ScriptResults.Success
End Sub
For anybody else struggling with this issue the resolution for me was as follows: (note I am NOT using User:: when getting variable values within my script task)
On the package Properties I hadn't included the variables as ReadOnlyVariables
You'll need to set your newly added variables as follows:
Right click on the package and select Edit
In the Script section click on ReadOnlyVariables or ReadWriteVariables (depending on your how you want your variables behave)
Check the check-box beside the variables you wish to use in your script task
Click Ok to save your changes
Hope this helps
I just had the same issue and unable to find the problem for ages. I found that the reason for the error was that I had missed one of the colons between "User" and the variable name.
I had this (which caused the error):
string FileName = UserVariables["User:CurrentFileName"].Value.ToString();
when I should have had this:
string FileName = UserVariables["User::CurrentFileName"].Value.ToString();
just in case anyone else has the same problem :)
Ohhh.........man. It's amazing how you can stare at this stuff and miss something stupid, for hours.
strFooter was missing in the listing.
ALL SET NOW. Sincere thanks to those who looked and commented. Eric, thanks, I'll remember that as sometimes I will probably need to use C insatead of VB (haven't yet but will).
Had a similar issue, after a lot of debugging, realized that the variable naming convention should be User::varname and NOT USER::varname
I guess c# is very case sensitive.
Hope this helps and saves you lot of your valuable time :-)
a) Right click on the script task and choose edit
b) Locate the Read or Read/Write variables properties in the list.
c) Click on the property and the variable you wish to access in the script task.
Another variation on "have been staring at the screen for too long to see the typo". In my case, I got the same error by mixing up the syntax between Project Params and User variables, and adding a $ sign in front of User.
error :
string varA = (string)Dts.Variables["$Project::ParamA"].Value
string varB = (string)Dts.Variables["$User::ParamB"].Value
corrected :
string varA = (string)Dts.Variables["$Project::ParamA"].Value
string varB = (string)Dts.Variables["User::ParamB"].Value
Has anyone had problems inserting a PNG file into a word document, using a VBA Macro?
I have an MS Word document that contains a very large directory listing of image files, inside a table. I've been asked to update the document by inserting the corresponding image in front of the name.
Now, if I enter the image manually (using Insert|Image|From File), I'm able to successfully place the PNG image ... so I decided to write a quick VBA Macro to insert the image for me. The following is a sample of the code:
Dim myFile As String
Selection.SelectCell
Selection.Copy
myFile = _
Chr(34) & "C:\Documents and Settings\...\Project\Images\" _
& Left(Selection.Text, Len(Selection.Text) - 2) & Chr(34)
Selection.InlineShapes.AddPicture _
FileName:=myFile, LinkToFile:=False, SaveWithDocument:=True
Outcomes:
Whenever I execute the macro, I get the "Unable to Convert" error dialog, and no image is inserted.
I even changed the code to invoke the wdDialogInsertPicture Dialog instead, and it worked just fine.
This is very confusing ... using a manual process, the insert works, but going with an automated solution, the insert doesn't work!
Any ideas or suggestions?
I've tried the macro several times and it works ... it seems that I'm no longer able to re-create the error again. So, I'm going to mark this under the "mysteries of Office VBA" column and leave it as is ... this is not a high-priority project, so there is no need for me to continue investigating.
Thanks to Alain and Joel Spolsky for their help.