Any way to determine when Excel background printing has finished? - excel

I'm using COM in LotusScript (Lotus Notes) to make Excel print several sheets in one workbook to PDFCreator, then make PDFCreator combine then into one PDF.
The problem is that calling Excel's PrintOut method immediately followed by PDFCreator's cCombineAll method results in one or more sheets being omitted from the PDF. It seems like Excel's PrintOut method returns before printing is complete.
Putting a Sleep in my code works, but may not be reliable as the printing time varies, so...
Is there any Excel property or method I can call to determine whether printing has finished?
Alternately, is there a way make the PrintOut method block until printing is finished?
I haven't been able to find an answer in Excel's VBA Help.

This sample code from excelguru.ca suggestst you need to use the cCountOfPrintJobs property of PDFCreator to monitor when the job starts and stops printing. Once printing is complete, you can perform whatever other operations you need
Set pdfjob = New PDFCreator.clsPDFCreator
' ...missing out various initialisation steps
'Print the document to PDF
ActiveSheet.PrintOut copies:=1, ActivePrinter:="PDFCreator"
'Wait until the print job has entered the print queue
Do Until pdfjob.cCountOfPrintjobs = 1
DoEvents
Loop
pdfjob.cPrinterStop = False
'Wait until PDF creator is finished then release the objects
Do Until pdfjob.cCountOfPrintjobs = 0
DoEvents
Loop
pdfjob.cClose

I think the other method is to set the "Background" argument of "PrintOut" to false.

Related

Excel VBA code that Copy/Pastes into a word document is causing my code to fail

I have an excel sheet
Which is generating a word document (which then gets converted into PDF)
The code loops through various rows of data and creates a page in word based on the data
Part of the loop takes a Graph from Excel and pastes it into the word page.
The code all works fine, and it generates the word document the way I want it. But the copy/paste of the chart is causing me intermittent issues.
The strange behaviour is that :
1 - My code will suddenly exit before it's finished looping through the data.
2 - I can't step through the code using F8 in break mode, as soon as I get to the code that does the pasting, the code just runs everything.
3 - if I put a break point just after the paste, and let the code stop and press f5 continuously, then I don't get the code suddenly exiting.
(Sorry it's such a long explanation)
This is a snippet of my code where the problem is occuring
IndividualChartSheet.ChartObjects("IndividualCompletionChart").Copy
DoEvents
objRange.PasteSpecial Link:=False, DataType:=wdPasteMetafilePicture, Placement:=wdWrapSquare, DisplayAsIcon:=False
Application.CutCopyMode = False
DoEvents
Set myShape = objDoc.InlineShapes.Item(objDoc.InlineShapes.Count).ConvertToShape
myShape.WrapFormat.Type = wdWrapBehind
myShape.RelativeVerticalPosition = wdRelativeVerticalPositionPage
myShape.Top = InchesToPoints(2)
myShape.Left = InchesToPoints(-0.4)
objRange is a reference to a range in my word object.
I can get the code to run, by putting a breakpoint on the Application.CutCopyMode = False and then pressing F5. But I'm hoping to pass this tool on to other users, so I can't need to fix this.
I added in the DoEvents and the CutCopyMode = False after some searching.
I also tried moving the paste command into a seperate function.
But that didn't work.
In case anyone is interested I finally go to the bottom of it.
Such a weird one that it took me a really long time to figure out.
Basically part of my code that was constructing the word document was also adding in hyperlinks so the the person looking at my final output (word document converted to a pdf file) could jump around the document.
My hyperlinks and bookmarks were based on employee names and word didn't like me having non alphanumeric characters in the hyperlink/bookmark names. Once I removed those the code runs through without any problems now.

Calling Bloomberg BQL queries from Excel VBA

For complex reasons, I want to automate the calling of a Bloomi BQL query in VBA.
I am changing the inputs to a BQL.Query formula in the Excel sheet from a VBA script, and calling Application.Calculate to run the query. The display changes to "N/A Requesting Data ...". In the VBA I wait a bit (using Wait()) and even throw in a DoEvents() for good measure.
While rngOS.Value < 0
Application.Calculate
Sleep 2000 'Waits 2000 ms
DoEvents
Wend
Trouble is, the BQL.Query just doesnt return. Only when I end the VBA script, does the actual data come back into the worksheet.
Ideally I would have a synchronous way to just call BQL.Query from VBA and wait for the return.
All suggestions welcome!
Here is a pointer: https://stackoverflow.com/a/33667663/829571
In substance: schedule your function to run a bit later, check if BQL is done (for example by counting the number of "N/A Requesting Data") and if not done, schedule the function a bit later again, etc. Once the count of N/As is down to 0, you know the update is finished and you can proceed with the rest of your code.

Displaying an userform multiples times in a loop

I'm having trouble to loop an userform and get data from it.
My code is already properly working whenever I use it for a single use (out of the loop).
The objective is to send data obtained using the ComboBox values (which is done in the Userform code) in a sheet and this has to be done X times (X being defined by the user at the start of the code) but whenever I enter the loop, my userform is only displayed once.
I did see that some people used the vbModeless option but since I didn't notice any change, I thought of it being a hint but didn't find anything close to it that solved my problem.
Sub nouveau_controle()
Dim nbre_controle As Integer
nbre_controle = InputBox("Entrez le nombre de contrôles à effectuer")
For j = 1 To nbre_controle Step 1
Formulaire_nouveau_controle.Show vbModeless
Next j
End Sub
Thank you for any help you can give me.
If you open a form vbModeless, it means 2 things:
(1) you can continue to work with excel while the form is open
(2) your code will immediately continue to run after the Show
As the code continues to run, your code hits the Show-command without stop. When the user closes it, it is not reopened as the code is already executed completely
The opposite is to open the form modal (this is the default). Execution stops at the Show command and waits until the form is closed. In that case, you should see you form multiple times. Examples for typical modal forms are InputBox or MsgBox

uipath "for each" being time-consuming

i implemented a normal 'for each'-Loop (not the excel specific for each row) in my UIPath Project.
The for-each Loop looks through a datatable with previously retrieved data from an excel file.
The for-each-loop then itererates through the Data with an if-else behind it.
Lets say it is as follows:
for each item in dataTable:
if (content of item == "10")
{
write cell: "Test" into A + index.ToString()
// leads for instance to writing into excel column 'A1'
}
else
{ write cell: "ElseTest" into for C + index.ToString() }
-- I used the syntax just for presentation-purposes.. :D
-> So the problem is:
writing into the cells takes so much time, where else putting out a MessageBox with random text inside the if and elses is done in milli-seconds, so the for-each-loop can't be the problem...
I ran that process with task manager opened and found out that Excel starts up, CPU percantage increases heavily, immidiately jumps to 0%... same happens again, for each iteration through the loop.
Why is that?
Is there a more optimised way to do that?
I need the for-each structure, because I need to check if it's either value 1 or value 2 inside the cell...
One possible option is to use the Read Range activity, manipulate the DataTable object itself, and then at the end write said object back to the same range using the Write Range activity.
Here's an example. My sheet contains 100 rows with all numbers from 1 to 100 in column A. Whenever there's a "1" in the cell, the data will be overwritten (in the DataTable object).
I think opening excel on each iteration is the time consuming part so I suggest
open excel before your for each
use attach window activity (https://activities.uipath.com/docs/window-scope) inside your foreach to set focus on excel file
close excel after your foreach or when you are done with the excel file
I would strongly recommend reframework (https://github.com/UiPath/ReFrameWork/tree/master/Framework) if you are not using it. It is an excellent starting point for RPA projects.
If you are using reframework you can open your excel file in InitAllApplications.xaml do your operations in Process.xaml and close your excel inside CloseAllApplications.xaml.

VBA Automation Error (System call failed) while running Excel 2013 macro from Access 2013

I have an Access (2013) database that I use to store/process all of our data received from a Qualtrics online survey. The raw data downloaded from Qualtrics is in a csv file that's poorly formatted for importing to Access, so I've got a fairly complex Macro in Excel (2013) that I use to pre-process the data before importing to Access.
In Access, I use the following code to open the excel file that contains the macro, run the macro, save the workbook, and close it. This had been working well several for several months, but now when I run it, it stops near the end of the Excel Macro with the run time error: -2147417856 Automation error System call failed.
ActivateOrOpenWorkbook WbkName & ".xlsm", strWbkPath
appExcel.Run ProcName, ProcArg
appExcel.Workbooks(WbkName).Save
If appExcel.Workbooks.Count = 1 Then
appExcel.Quit
Else
appExcel.Workbooks(WbkName).Close True
End If
ActivateOrOpenWorkbook is just a custom function to do exactly what the name implies, appExcel is the Excel Application. The workbook always opens fine, and the macro begins to run, but it never actually reaches the point where control returns to the Access VBA and saves the workbook.
It does run fine if I open the Workbook before running the Access procedure, insert breakpoints at every major VBA step (in both Access and Excel), and step through the whole thing one Sub at a time. It just fails if I try to let VBA run it all from start to finish on it's own.
Based on that evidence plus stories of similar problems that I've seen online, I suspect that the error is occurring because the Excel macro is taking too long to run (we recently added some new variables to the Qualtrics survey), and Access is trying to take back control before Excel is finished. I just haven't found any viable way to solve that suspected problem or investigate it further.
I did try inserting this makeshift Wait routine into my ErrorHandling for the Access Sub, but it didn't work at all, because the error message still popped up in the same amount of time as before.
If Err = -2147417856 Then
TWait = Time
TWait = DateAdd("s", 15, TWait)
Do Until TNow >= TWait
TNow = Time
Loop
Resume Next
Any help will be appreciated!
Have you tried using DoEvents in the pre-processing macro?
If you have a loop where you're processing the CSV file line by line then use DoEvents every so often to give any pending events a chance to run. It would be overkill to call it on every line so maybe start with every 100 lines and adjust from there.
Given that the macro works when you step through the Subs, it would appear that it isn't the overall execution time that's the problem. If Access is throwing an error because Excel appears to be unresponsive then DoEvents might be enough to stop Access from giving up

Resources