Can I apply and execute a code from a different document? - vba

Is there a way to have two documents where the first document has all the code and functions that will execute and apply on the second document?
For example: Doc 1 has a button and all of the code, and when I press that button, it will draw shapes on doc 2.
I was wondering if DocumentOpened is the fitting method. Any help or tip would be appreciated. Thank you!
PS. My other question was closed so I had to make a new one...

As with any Office product, you can use the open application object to reference the document collection for that application.
Also, when you execute the Documents.Open function (or .Add function for new files) it will return a valid Document object. You then use that object to perform other operations.
Visio Documents.Open Method Documentation
' open existing document
Dim viDoc as Object
Set viDoc = Documents.Open(sFilename)
or
' create new document
Dim viDoc as Object
Set viDoc = Documents.Add(sFilename)

Related

Closing file without saving

I have a code block (which works) to open a file.
Dim AppVisio
Set AppVisio = CreateObject("visio.InvisibleApp")
Dim vsoDoc
Set vsoDoc = AppVisio.Documents.Open("PathName\Drawing1.vsd")
However, when this file is already open, I want it to be automatically closed without saving changes.
I could not find code such as
AppVisio.Documents.Close ("PathName\Drawing1.vsd")
Any other options to force close the file should it be open?
Dim vsoDoc
You've declared it as an implicit Variant - this would be equivalent:
Dim vsoDoc As Variant
And if you place a breakpoint immediately after the Set vsoDoc = statement, go to the immediate pane (Ctrl+G) and type
?TypeName(vsoDoc)
You'll see that it will print Document. Hence, you can declare it with a Document type instead:
Dim vsoDoc As Document
And then when you want to close this vsoDoc, you work with that object and call its Close method:
Set vsoDoc = AppVisio.Documents.Open("PathName\Drawing1.vsd")
'do stuff...
vsoDoc.Close
That vsoDoc variable is your document object. Declaring it As Document will give you IntelliSense/AutoComplete so when you type the dot in vsoDoc., you'll see a drop-down in the editor showing you all the document's members.
If you're already in Visio, there's no need to late-bind everything; you already have a reference to the Visio object model. Early binding makes it much easier to know which types are involved and what their members are.
The method you are looking for is part of the Document object (not Documents)
Click Here to see the Document Close Method

Close MS Project using VSTO

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

Reading, Writing and controlling Autocad using external VBA

I'm using MS-Access 2010 and Autocad 2012 64bit and work in manufacturing.
I want to be able to at the very least, populate fields in a title block, better still I would like to use data in my access database to write data into a sheet set (the current system works by reading the sheet set values such as sheet title and number into my title block).
The following code is all I have at the moment and it will open autocad and write the date into the command line.
Private Sub OpenAutocad_Click()
Dim CadApp As AcadApplication
Dim CadDoc As AutoCAD.AcadDocument
On Error Resume Next
Set CadApp = GetObject(, "AutoCAD.Application")
If Err.Number <> 0 Then
Set CadApp = CreateObject("AutoCAD.Application")
End If
On Error GoTo 0
CadApp.Visible = True
CadApp.WindowState = acMax
Set CadDoc = CadApp.ActiveDocument
CadDoc.Utility.Prompt "Hello from Access, the time is: " & TheTime
Set CadApp = Nothing
End Sub
I have no idea where to go from here. What are the commands to control the sheet set manager and change data, and can the .dst file be edited without even opening up autocad? is there a list of all available autocad vba commands and functions?
If you are declaring CadApp as AcadApplication you must have added a reference to AutoCAD.
That means you should be able to see the object model using your Object Browser in your VBA IDE. No?
There is also a very helpful site www.theswamp.org which has a whole section devoted to AutoCAD VBA.
If I understand your question correctly, you want to automate filling attributes in a drawing title blocks (such as title, drawer, part number, etc) right from MS Access.
Your code can access the Autocad command line already, but Autocad doesn't seem to have the exact command for filling drawing attribute. (command list)
So looks like you need to fill the attributes programatically using the COM API.
The following question appears to be relevant with yours and the accepted answers does provide a sample code:
Is it possible to edit block attributes in AutoCAD using Autodesk.AutoCAD.Interop?
Note that in that question the asker was developing a standalone application in C# .NET, where as you will be using VB Automation from MS Access. Shouldn't be too different since the Component Object Model (COM) being used is the same.
What are the commands to control the sheet set manager and change data and can the .dst file be edited without even opening up autocad?
(sorry can't post more than 2 links)
docs.autodesk.com/ACD/2010/ENU/AutoCAD%202010%20User%20Documentation/files/WS1a9193826455f5ffa23ce210c4a30acaf-7470.htm
No mention about data change, though.
is there a list of all available autocad vba commands and functions?
Yes.
%ProgramFiles%\Common Files\Autodesk Shared\acad_aag.chm - Developer's Guide
%ProgramFiles%\Common Files\Autodesk Shared\acadauto.chm - Reference Guide
Online version:
help.autodesk.com/cloudhelp/2015/ENU/AutoCAD-ActiveX/files/GUID-36BF58F3-537D-4B59-BEFE-2D0FEF5A4443.htm
help.autodesk.com/cloudhelp/2015/ENU/AutoCAD-ActiveX/files/GUID-5D302758-ED3F-4062-A254-FB57BAB01C44.htm
More references here:
http://usa.autodesk.com/adsk/servlet/index?id=1911627&siteID=123112
:) Half the way gone ;)
If you has a open autocad with a loaded drawing you can access the whole thing directly.
Sub block_set_attribute(blo As AcadBlockReference, tagname, tagvalue)
Dim ATTLIST As Variant
If blo Is Nothing Then Exit Sub
If blo.hasattributes Then
tagname = Trim(UCase(tagname))
ATTLIST = blo.GetAttributes
For i = LBound(ATTLIST) To UBound(ATTLIST)
If UCase(ATTLIST(i).TAGSTRING) = tagname Or UCase(Trim(ATTLIST(i).TAGSTRING)) = tagname & "_001" Then
'On Error Resume Next
ATTLIST(i).textString = "" & tagvalue
Exit Sub
End If
Next
End If
End Sub
Sub findtitleblock(TITLEBLOCKNAME As String, attributename As String,
attributevalue As String)
Dim entity As AcadEntity
Dim block As acadblcck
Dim blockref As AcadBlockReference
For Each block In ThisDrawing.BLOCKS
For Each entity In block
If InStr(LCase(entity.objectname), "blockref") > 0 Then
Set blockref = entity
If blockref.effectivename = TITLEBLOCKNAME Then
Call block_set_attribute(blockref, attributename, attributevalue)
exit for
End If
End If
End If
Next
Next
End Sub
call findtitleblock("HEADER","TITLE","Bridge column AXIS A_A")
So assume you has a title block which has the attribute TITLE then it will set the Attribute to the drawing name. it mioght also possible you has to replace the thisdrawing. with your Caddoc. I usually control Access and Excel form autocad and not vice versa ;)
consider also to use "REGEN" and "ATTSYNC" if "nothing happens"
thisdrawing.sendcommens("_attsync" 6 vblf )

VBA - Documents.Activate function does not work properly

I'm not very used to VBA language, so I come to you for help to solve my problem.
Basically, what I want to do is, while having a MS Word 2010 document opened, open a new one, set the focus on it and do stuff with it.
The problem I'm facing is that I can effectively open the new document, but the .activate function to set the function on it doesn't work, as the instructions following it are still executed in the first document.
Here is my code:
Private Sub BOK_Click()
*...instructions...*
'Opens a new document
Application.Documents.Add
'Select the latest opened document and sets the focus on it
Application.Documents(Application.Documents.Count).Activate
* do stuff *
End Sub
If it may help, the full context is :
I have a main template with 6 pre-filled templates in it, and following the choice of the user (from a drop-down form) it selects the right pre-filled template and opens it in a new Word document, then closed the main template.
What Documents.Add does:
Create a window
Render a copy of the provided (or Normal, in this case) template
Display it in the window
Raise the index of all open documents by 1
Assign index 1 to the newly added document
Bring the window to the front and give focus to it
There's (usually) no need to explicitly activate a document you just added. If you must or want to use Activate, it's best practice to reference a document by it's name, since indexes tend to drift (as described above).
doc1 = ActiveDocument.Name
Documents.Add
doc2 = ActiveDocument.Name
' Do something with document2
Documents(doc1).Activate
' Do something with document1
Documents(doc2).Activate
' Do something with document2 again

How do I programatically add a reference to a VBA project?

I'm deploying an early bound styled VBA module that needs Scripting.Dictionary and RegExp.
The script, predictably, fails when it runs on another computer.
The user has to go to Tools->Reference in the VBA IDE and add a reference to those two libraries manually to make it work.
Hence lies the problem. Asking the non-technical end user to go to the IDE and manually add references is asking way too much of them.
The other alternative is to rewrite the whole (very long script written by someone else) to use late binding. I rather not take this path if there are other methods.
As an altervative, some people suggest adding a reference programatically like so:
Application.VBE.ActiveVBProject.References.AddFromFile [Path to library]
Is this the correct solution and if so are there any downsides of this strategy?
If not, are there other methods that will to enable the code to remain early bound yet does not require references to be added manually by the user.
Suggestions involving direct calls to the Win32/64 API are also welcome.
Thanks.
In my own limited environment (small # of other people using spreadsheets I develop, relatively standard machine setups), if I create the file and add the references, and then give a copy to someone else, they can open it with no problems and not have to do anything, so keep that in mind with this answer. (I'm wondering why that doesn't work for you.) Also, this was with Excel.
Rather than adding a reference from a file path, you might consider using the GUID property instead.
Here is some code I once used to automatically create references in a newly created workbook. (It's part of a script that would export code, references, and unit tests on worksheets to text for use with Subversion and then later reconstitute the workbook from the text files.) You might find it useful to your situation. (EH and cleanup removed to keep it short...)
'Export refs in existing workbook to text file
Private Sub exportRefs_(srcWbk As Workbook)
Dim fs As FileSystemObject
Set fs = New FileSystemObject
Dim tsout As TextStream
Set tsout = fs.CreateTextFile(fs.BuildPath(getTargetPath_(srcWbk), "refs.refs"))
Dim ref As Reference
For Each ref In Application.ThisWorkbook.VBProject.References
Call tsout.WriteLine(ref.GUID)
Next ref
'<EH + cleanup...>
End Sub
'Add refs to newly created workbook based on previously exported text file
Private Sub importRefs_(wbk As Workbook, path As String)
Dim fs As FileSystemObject
Set fs = New FileSystemObject
Dim tsin As TextStream
Set tsin = fs.OpenTextFile(path)
Dim line As String
Dim ref As Reference
While Not tsin.AtEndOfStream
line = tsin.ReadLine()
Set ref = Nothing
On Error Resume Next
Set ref = wbk.VBProject.References.AddFromGuid(line, 0, 0)
On Error GoTo 0
If ref Is Nothing Then
Debug.Print "add failed: " & line
End If
Wend
'<EH + cleanup...>
End Sub
Like, I said, limited environment, but hopefully it helps.