I am getting a compile error when trying to include a timeout as part of the Save as action for Microsoft word on Blue Prism.
Code Stage:
ExecWithTimeout(Timeout, "Save As",
Sub()
Dim doc as Object = GetDocument(handle,documentname)
doc.SaveAs(filename)
newname = doc.name
End Sub)
Error:
Page: Save As
Stage: SaveAs
Type: Error
Action: Validate
Description: Compiler error at line 1: 'ExecWithTimeout' is not declared. It may be
inaccessible due to its protection level.
Repairable: No
As you correctly indicated, the Blue Prism MS Excel VBO contains the custom ExecWithTimeout function, but the same is not included by default in the MS Word VBO.
The solution for you might be to copy the entire Private Sub ExecWithTimeout block from the Global Code tab within the MS Excel VBO's Business Object Properties window:
Once copied, you can paste it into the same Global Code tab for the MS Word VBO.
However, modifying the default VBOs is generally a very bad idea as future releases of the Blue Prism platform will likely overwrite your customizations. I would implore you to review the guidance on modifying these VBOs before continuing.
Related
I want to store source code of VBA macro in .bas or .txt file and run it when user runs macro. I have macro that is used by multiple people, and I would like to store file on server to prevent them to use older versions of same macro. I found following line in stackoverflow and placed it in module code that should import code
'Library should be turned on Microsoft Visual Basic for Applications Extensibility 5.3
Option Explicit
Sub main()
Dim VBPrj As VBIDE.VBProject
Dim VBCom As VBIDE.VBComponent
Set VBPrj = Application.VBE.ActiveVBProject
Set VBCom = VBPrj.VBComponents("Module1")
VBCom.CodeModule.AddFromFile ("C:\Users\lietu\OneDrive\Documents\tests\Module1.txt")
End Sub
then I created txt file with following code in right location
Attribute VB_Name = "Module1"
Sub main()
MsgBox "Hello World"
End Sub
What I'm doing wrong?
It is not possible to execute code in a text file as a VBA "macro". The programming language/environment/interface simply does not work that way - no ifs, ands or buts - no workarounds.
The content of a text or bas file must be imported into a VBA project, using code similar to what's in the question.
In order to be able to use the VB Extensibility libraries that this code depends on, a specific security setting in the host Office application must be disabled, making this kind of approach unreliable, at best. The setting cannot be disabled using code, for understandable reasons.
Indeed, the approach proposed in the question would be a massive security risk...
I have a VSTO on MS Project. I use VB.NET. What I need is when I press the button I created on the ribbon, it will perform some codes which will update the info of some task, however, I would need to close the MS Project automatically. I tried application.FileCloseEx(), but it only closes the file, the MS Project is still loaded. I need similar to clicking the x button of the window.
Thanks,
Gilbert
If your MS Project application object is represented by "appMSProject" then it's as simple as:
appMSProject.Quit
OR say in a macro running under Project:
Application.Quit
Here's how I do it in VBA from Excel or Access. As far as I can tell the objects & methods are the same in VB.NET. Bottom line is that I create an instance of the MS Project object which starts the app & opens a file, execute some work, close the file, then destroy the MS Project object by setting it to Nothing. That has the effect of closing the app. You can also use "appMSProject.Quit" followed by setting it to Nothing. Frankly the 2nd option looks more orderly & easier to understand in code. Anyway, here's a sample of the way I do it:
Dim appMSProject As MSProject.Application
Dim prjPrj As MSProject.Project
Dim strPrjFile As String
strPrjFile = "C:\where_is_my_file\file_name.mpp"
Set appMSProject = New MSProject.Application
appMSProject.FileOpenEx Name:=strPrjFile
Set prjPrj = appMSProject.ActiveProject
'''Do something in here with the prjPrj
'Close the file, in my case w/o saving
appMSProject.FileCloseEx pjDoNotSave
'Destroy the objects
Set prjPrj = Nothing
Set appMSProject = Nothing
FYI - In this example I'm doing background work so I don't show the app. I also use "early binding".
Here's an MSDN example that does show the app with more info on early -vs- late binding - https://msdn.microsoft.com/en-us/library/office/ff865152.aspx
I have a Word .dot file which works in older versions of Word but fails with error 432 when run in Word 2013.
When I debug the code I have the line:
Load customerForm
And VBA shows the error:
Run-time error '432': File name or class name not found during Automation operation
The project "pennyscode" includes "Module1" which contains the function being debugged, "ThisDocument" and a form called "customerForm".
I have tried changing the name to "pennyscode.customerForm" but this doesn't make any difference.
This code is being called from a Sub function which is called from Document_New().
Updates
I can place a breakpoint on the Load customerForm line and demonstrate that it is the line that is causing the problem. If at this point I mouse over the word "customerForm" VBA comes up with
customerForm = <Object variable or With block variable not set>
If I delete/skip the Load line then the next line is customerForm.Show and that produces the same error.
If I just open the .dotm file and then use Alt-F11 to open VBA, I can look at the code for selectCustomer, list properties/methods and customerForm appears in the list.
Additional Note
I believe that within the Load function it must be calling GetObject and it is this that is failing. It is as if VBA can't find the customerForm object even though it appears in the project.
I've posted the full code of the function being called from Document_New below.
Sub selectCustomer()
Dim Doc As Document
Set Doc = Application.ActiveDocument
If Doc.CustomDocumentProperties.Item("Customer") = "Nothing" Then
Load customerForm
customerForm.Show
Unload customerForm
Doc.Fields.Update
a$ = Doc.CustomDocumentProperties.Item("InvoiceNumber")
a$ = customerForm.pathBox.Value + "\" + a$
Doc.SaveAs (a$)
End If
End Sub
I've also posted the full .dotm (Excel 2013) and .dot (previous excel) and some sample data (.xls) here:
Dropbox/Public/Invoice 2015-16.dotm
Dropbox/Public/Invoice 2015-16.dot
Dropbox/Public/data.xls
Update
I've not had much luck making progress on this question. Can anyone suggest an approach to investigating this? Or how I might improve the information on the question?
I finally managed to fix this, and I have a few learnings.
Firstly the debugger shows the error as occurring on the Load customerForm line, but this is actually not the case.
The customerForm has an _Initialize function which loads data into it before it is displayed. This function was failing with but the debugger stops on the wrong place.
I was able to debug this more effectively by putting a breakpoint on the start of the _Initialize sub and then stepping through the code.
Once I had discovered this I realized that the code was failing to find the XLSX file due to a wrong path, thus causing the run-time error.
Once I'd fixed up all the paths, I then hit a second error: runtime error '9' which is a subscript problem. This also reported on the Load customerForm line and was also due to a problem with the _Initialize function.
This was the true source of the problem, and demonstrated a functional change between Office 2013 and previous versions of Office.
My code was opening an XLSX file and attempting to read data from it:
Dim myXL As Object
Dim myWS As Object
Set myXL = GetObject("C:\Test\data.xlsx")
myXL.Application.Visible = True
myXL.Parent.Windows(1).Visible = True
Set myWS = myXL.Application.Worksheets("Customers")
The run-time error 9 was due to the index of the Windows property, as their were no windows. In previous versions of Office, there was a single window, with 2013 the array is empty.
After much messing about I tried adding this line:
myXL.Activate
before accessing the Windows() array. Once that was executed Windows(1) existed and the code worked as before.
Hope this can help someone else struggling with similar problems.
I'm using Microsoft Office 2003 and creating a bunch of template documents to standardize some tasks. I asked this on Superuser.com and got no response so I'm thinking it's too program-y and hoping I'll have better luck here.
I need to automate a work flow that uses a bunch of Office (mostly Word) templates. What I want is to have "My Template Foo.dot" and "My Template Bar.dot", etc. in the "My Foo Bar Stuff" on a shared drive and have users double click on a template to create a new Foo or Bar.
What's I'd really like is for the user to double-click on the Foo template and be prompted for a couple of items related to their task (e.g., a project number) and have a script in the template change the name that Save will default to something like "Foo for Project 1234.doc".
I asked on Google Groups and got an answer that worked....for a while. Then my AutoNew macro stopped kicking in when I created a new document by double-clicking on the template. I have no idea why or how to debug it.
In Class Modules/This Application, I have:
Sub AutoNew()
Dim Project As String
Project = InputBox("Enter the Project Number")
ActiveDocument.SaveAs "Project " & Project & " Notes.doc"
End Sub
In Microsoft Word Objects/ThisDocument, I have:
Private Sub Document_New()
End Sub
I really have no idea why or where that came from.
In Tools/Macro Security... I have Security Level set to "Low".
I'm a software engineering with 25+ years of experience but a complete Office automation noob. Specific solutions and pointers to "this is how to automate Word" FAQs are welcome. Thanks.
Update: If I create a new template (New..., Blank Document, Save As "My New Template.dot"), and insert the AutoNew() macro, it works. So what's inhibiting it from working on my existing template?
Update 2: Removing the module and function from my old template and adding it back works, too.
You can attach a template to a saved document in ordre to access the macros contained in the template in question.
You can do this with the AttachedTemplate property of a Document object (i.e. ActiveDocument).
Please note that I did not try this myself.
Sub AutoNew()
Dim Project As String
Project = InputBox("Enter the Project Number")
ActiveDocument.SaveAs "Project " & Project & " Notes.doc"
ActiveDocument.AttachedTemplate = "\\path\to\templates\My Template Foo.dot"
End Sub
See MSDN - Word 2003 VBA Language Reference - AttachedTemplate Property
Hope that helps.
Check if the macro is still contained in your template. This sounds stupid but it happended to me, too, in Word 2003 under the following circumstances:
Create a template containing macro,
everything fine
Create a new document file based on
the macro, macro kicks in
Notice I could improve the template
here and there a bit, I do it in the
file created in 2) and SaveAs .DOT
Macro in .DOT GONE!
Why? Because the code stored in the .DOT doesn't go over to the doc file.
As per my application I want to write some Lines code in "ThisWorkbook" of Excel file using vb.net,before that we need to check the file for existance of code.
Please let me know any code or links for reference..
thank you...
It's possible but it's also very likely that the user's macro security settings will prevent this from working initially.
To adjust the security settings (all examples for Excel 2003):
(from a workbook): Tools > Macro > Security > Trusted Publishers
You now need to check the box which says "Trust access to Visual Basic project"
To read the code:
(from the VBA editor): Tools > References and add "Microsoft Visual Basic For Applications Extensibility 5.3" (the actual file is VBE6EXT.OLB)
To work out which VBProject is which, use the FileName property:
For Each vbpItem In Application.VBE.VBProjects
If (vbpItem.FileName = "C:\foo.xls") Then
Set vbpProject = vbpItem
End If
Next vbpItem
Once you have the project, you can refer to the module by name:
vbpProject.VBComponents("ThisWorkbook")
and you can check how many lines there are like this:
If (vbpProject.VBComponents("ThisWorkbook").CodeModule.CountOfLines <> 147) Then
With the CodeModule object, you can read back specific lines (via the Lines property) and change lines (with the ReplaceLine method)
The only thing I can find that would do this is ThisWorkbook.VBProject.VBComponents.Count which counts the number of Modules in your VB solution, which is Sheets + ThisWorkbook + anything additional. I can't find anything that would let you do a diff of the code.
Are you trying to do a security check of some sort? If random code was being inserted into your workbooks, wouldn't a black hat delete this coded in check? Why not just use signatures and digitally sign it?