I have a lookup function in Excel (2010) that maps to a google for getting zip code data. I have some cells with formulas to look up against the XML data remotely: I have one cell named ZipCode. The code below updates city and state based on a newly typed zip code.
Here is the code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row = [ZipCode].Row And Target.Column = [ZipCode].Column Then
Dim Zip As String: Zip = [ZipCode].Value
If Len(Zip) <> 5 Or Not IsNumeric(Zip) Then
MsgBox "Please enter a valid zip code!", vbCritical, "Invalid Zip"
Exit Sub
End If
Dim Map As XmlMap
Set Map = ActiveWorkbook.XmlMaps(1)
Map.DataBinding.LoadSettings "https://maps.googleapis.com/maps/api/geocode/xml/?address=" & Zip & "&sensor=false"
Map.DataBinding.Refresh
End If
End Sub
The routine fails at:
Map.DataBinding.LoadSettings "https://maps.googleapis.com/maps/api/geocode/xml/?address=" & Zip & "&sensor=false"
with the following runtime error
runtime error -214721376 (80041020) The system could not locate the object specified.
I am not having much luck in understanding why it is failing. Any help would be appreciated.
The URL is incorrect:
https://maps.googleapis.com/maps/api/geocode/xml/?address=
The URL should be:
https://maps.googleapis.com/maps/api/geocode/xml?address=
(also the sensor parameter is no longer required)
I'm no expert...but I know the video you are watching and I got this error. You aren't specifying to excel the proper xml source. Your code is perfect as per the video, but my guess is that you messing up here:
Set Map = ActiveWorkbook.XmlMaps(1)
This may not be referring to the correct xmlmap. I would suggest deleting the source files and reloading the xml map again.
Related
In VBA I can see three different references for PDFCreator. One of them (see the second image) is a version of the software stored locally, and it works. I'd like to use this reference.
The other two are references to versions stored on a server, and they're broken (at this stage, I don't have permission to reinstall or delete them).
My problem is that after selecting the desired reference (see the second image) and clicking 'Ok', it resets to an incorrect reference, as shown in the third image.
How can I either override whatever's going on and select the desired reference or remove the incorrect references? While I'm not able to uninstall these versions from the server, I see no reason that my Excel would need to reference them. Can they just be removed from the list?
Image 1: Default state of the VBA Project References (PDFCreator not selected)
Image 2: Selecting the correct PDFCreator version
Image 3: Re-opening the menu shows that the incorrect PDFCreator version is selected
You might be able to something like the following...
To Remove broken references:
Private Sub RemoveBrokenReferences(ByVal Book As Workbook)
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Dim oRefS As Object, oRef As Object
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Set oRefS = Book.VBProject.References
For Each oRef In oRefS
If oRef.IsBroken Then
Call oRefS.Remove(oRef)
End If
Next
End Sub
To Remove a specific reference:
Use something like:
Call ActiveWorkbook.VBProject.References.Remove(oReference)
and you can get the oReference from:
Private Function GetReferenceFromPath(ByVal FilePathName As String) As Object
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Dim oFs As Object, oReferenceS As Object, oReference As Object
Dim sFileName As String, sRefFileName As String
'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Set oFs = Interaction.CreateObject("Scripting.FileSystemObject")
sFileName = oFs.GetFileName(FilePathName)
Set oReferenceS = ActiveWorkbook.VBProject.References
For Each oReference In oReferenceS
sRefFileName = oFs.GetFileName(oReference.FullPath)
If StrComp(sFileName, sRefFileName, vbTextCompare) = 0 Then
Set GetReferenceFromPath = oReference
End If
Next
End Function
Public Sub RemoveReference()
On Error GoTo EH
Dim RefName As String
Dim ref As Reference
RefName = "Selenium"
Set ref = ThisWorkbook.VBProject.References(RefName)
ThisWorkbook.VBProject.References.Remove ref
Exit Sub
EH:
'If an error was encountered, inform the user
Select Case Err.Number
Case Is = 9
MsgBox "The reference is already removed"
Exit Sub
Case Is = 1004
MsgBox "You probably do not have to have Trust Access To Visual Basic Project checked or macros enabled"
Exit Sub
Case Else
'An unknown error was encountered
MsgBox "Error in 'RemoveReference'" & vbCrLf & vbCrLf & Err.Description
End Select
End Sub
P.S It is not possible to remove A MISSING/ broken references programmatically after MISSING occurs, only before it happens or manually after it happens. Most cases of MISSING/ broken references are caused because the type library has never before been registered on that system.
See How to Remove Reference programmatically?
I had a broken reference problem with a large number of Excel spreadsheets when I uninstalled Flash (which for some unknown reason I had included as a reference).
I got round the problem as follows:
BE CAREFUL BECAUSE THIS INVOLVES A REGISTRY HACK AN IS COMPLICATED.
MAKE A BACKUP OF REGISTRY BEFORE HACKING.
I wrote VBA code to find the Guid of the broken reference.
I used Regedit to insert a DUMMY TypeLib entry as follows:
D27CDB6B-AE6D-11CF-96B8-444553540000 was the Guid of the Broken Reference.
HKEY_CLASSES_ROOT\TypeLib{D27CDB6B-AE6D-11CF-96B8-444553540000}
HKEY_CLASSES_ROOT\TypeLib{D27CDB6B-AE6D-11CF-96B8-444553540000}\1.0 Adobe Acrobat 7.0 Browser Control Type Library 1.0
HKEY_CLASSES_ROOT\TypeLib{D27CDB6B-AE6D-11CF-96B8-444553540000}\1.0\0
HKEY_CLASSES_ROOT\TypeLib{D27CDB6B-AE6D-11CF-96B8-444553540000}\1.0\0\win32 C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroPDF.dll
HKEY_CLASSES_ROOT\TypeLib{D27CDB6B-AE6D-11CF-96B8-444553540000}\1.0\FLAGS 0
HKEY_CLASSES_ROOT\TypeLib{D27CDB6B-AE6D-11CF-96B8-444553540000}\1.0\HELPDIR C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\
I based the above on another TypeLib entry.
Then I wrote VBA code to read each Reference.Guid in turn and if the Guid matched {D27CDB6B-AE6D-11CF-96B8-444553540000} to remove the reference using References.Remove Reference.
Code for doing this is available all over the forums so I won't repeat here.
After modifying all the affected Workbooks I reinstated the saved registry.
Hope this works for you.
BE CAREFUL BECAUSE THIS INVOLVES A REGISTRY HACK AN IS COMPLICATED.
MAKE A BACKUP OF REGISTRY BEFORE HACKING.
I am working on a project to process some incoming Outlook messages using rule-triggered VBA code.
However, I don't want to have to manually update the code for each user's inbox any time the code needs to change. So my idea is to put a text file on a shared drive and have the VBA pull that text file down and treat it like code. Essentially, I want to use that text file like a little code library.
I was able to find this link that has gotten me very close to my goal. However, I'm having a few issues with it.
Here is the code I put together. It is attached to the click event of a Rectangle shape I inserted into an Excel file. Eventually, I'll move this over to Outlook, but I'm just doing a basic test with Excel VBA first.
Sub Rectangle1_Click()
On Error GoTo Err_Handler
Dim enviro As String
Dim myFile As String
'Pull code "library" from text file on user's desktop
'This will eventually be changed to reside on a shared drive
enviro = CStr(Environ("USERPROFILE"))
myFile = enviro & "\Desktop\hello_vba.txt"
'If the "Library" module already exists, delete it
For Each a In Modules
If a.Name = "Library" Then
a.Delete
Exit For
End If
Next
'Add a new module
Set m = Application.Modules.Add
'Rename it to "Library"
m.Name = "Library"
'Insert the text from the other file to this new module
m.InsertFile myFile
'Call the hello() subroutine from the retrieved text file
Library.Hello
Exit_Here:
'Cleanup code goes here
Exit Sub
Err_Handler:
MsgBox Err.Description
Resume Exit_Here
Exit Sub
And here is the content of the external text file named "hello_vba.txt":
Sub Hello()
MsgBox "Hello"
End Sub
The first time I run this, using the debugger I can see that it creates the new module and then gets to the line that says:
m.Name = "Library"
And then a window pops up in the debugger that says:
Can't enter break mode at this time
When I click continue on that message, I get an
Object Required
error message. If it run it again, then I get some more error messages but I do eventually get a successful "Hello" message box pop up.
I'm wondering if I may not have "Dim"ed the "a" or "m" variables properly or if there is a problem trying to pull in a text file and immediately treat it like code?
Any ideas?
To run your new code, try using Application.Run instead of Library.Hello
It would be written:
Application.Run("Hello")
Does that work?
I have been using folder browser for VBA, I could paste the code of it, but bottom line is that I get returned file name as a string.
Is there any way to access drawing properties (i.e number of layouts) without open?
Public Sub TestFileDialog()
dwgname = FileBrowseOpen("C:", "*", ".dwg", 1) 'dwgname is typeof string
End Sub
Its only the first step (use of FileBrowseOpen function is shown, but also i can use FolderBrowse and collect all .dwg inside of folder),actually i had in mind to batch export all layouts of selected .dwgs to currenty open one. Is there any chance for that?
To effectively read a .dwg file you'll need to open AutoCAD, otherwise the information is not accessible. Some properties may be, such as author, but not number of layouts...
But you can use AutoCAD Console (accoreconsole.exe) to run a headless AutoCAD and use APIs to read any information you need. This is really fast for reading lot's of files and the user will not see it running (but it needs to be installed anyway).
http://aucache.autodesk.com/au2012/sessionsFiles/3338/3323/handout_3338_CP3338-Handout.pdf
you could stay in VBA and use ObjectDBX
it leads to a very similar approach as accoreconsole.exe on in .NET does, i.e you won't see any drawing open in UI since it works on the database itself
It requires adding library reference (Tools->References) to "AutoCAD/ObjectDBX Common XX.Y Type Library", where "XX.Y" is "19.0" for AutoCAD 2014
a minimal functioning code is
Sub main()
Dim myAxDbDoc As AxDbDocument
Dim FullFileName As String
FullFileName = "C:\..\mydrawing.dwg" '<== put here the full name of the file to be opened
Set myAxDbDoc = AxDb_SetDrawing(FullFileName)
MsgBox myAxDbDoc.Layers.Count
End Sub
Function AxDb_SetDrawing(FullFileName As String) As AxDbDocument
Dim DBXDoc As AxDbDocument
Set DBXDoc = Application.GetInterfaceObject("ObjectDBX.AxDbDocument.19") '<== place correct AutoCAD version numeber ("19" works for AutoCAD 2014)
On Error Resume Next
DBXDoc.Open FullFileName
If Err <> 0 Then
MsgBox "Couldn't open" & vbCrLf & vbCrLf & FullFileName, vbOKOnly + vbCritical, "AxDB_SetDrawing"
Else
Set AxDb_SetDrawing = DBXDoc
End If
On Error GoTo 0
End Function
Still, you must have one AutoCAD session running from which make this sub run! But you should have it since talked about "currently open" drawing
I've been searching around on Google to find a better way to show images in Access without actually inserting the image into the database.
I found this article 'http://support.microsoft.com/kb/285820' via this thread 'Is there a way to get ms-access to display images from external files' which goes into great detail on how to set paths to pictures through folders/files, and it works great, for a 'set' picture. However, I want a different picture to display when I switch to a different record.
Here is the code from the article:
Option Compare Database
Option Explicit
Public Function DisplayImage(ctlImageControl As Control, strImagePath As Variant) As String
On Error GoTo Err_DisplayImage
Dim strResult As String
Dim strDatabasePath As String
Dim intSlashLocation As Integer
With ctlImageControl
If IsNull(strImagePath) Then
.Visible = False
strResult = "No image name specified."
Else
If InStr(1, strImagePath, "\") = 0 Then
' Path is relative
strDatabasePath = CurrentProject.FullName
intSlashLocation = InStrRev(strDatabasePath, "\", Len(strDatabasePath))
strDatabasePath = Left(strDatabasePath, intSlashLocation)
strImagePath = strDatabasePath & strImagePath
End If
.Visible = True
.Picture = strImagePath
strResult = "Image found and displayed."
End If
End With
Exit_DisplayImage:
DisplayImage = strResult
Exit Function
Err_DisplayImage:
Select Case Err.Number
Case 2220 ' Can't find the picture.
ctlImageControl.Visible = False
strResult = "Can't find image in the specified name."
Resume Exit_DisplayImage:
Case Else ' Some other error.
MsgBox Err.Number & " " & Err.Description
strResult = "An error occurred displaying image."
Resume Exit_DisplayImage:
End Select
End Function
I have a feeling that I need to place a line of code that states something like, show image where Image.ID = "ID", but I can't figure out where to put it without getting errors. Am I over-looking something perhaps, or am I approaching this the wrong way? I just don't want to clutter my database, memory-wise, with .bmp images, but I feel like I am going to have to.
SOLVED: A much easier solution is as Gord Thompson has described below in the comments. And from my own experience, using this method for .bmp images leaves the picture distorted and out of contrast. I tested the image for .jpg and it worked perfectly! I hope this helps others who are having trouble with similar problems finds this post helpful.
The Microsoft Support article you cited applies to Access 2003. In Access 2010 (and later) there is a much simpler way to do it. All you need to do is place an Image control on the form and bind it to the field in your table that contains the path to the image file.
For example, with an [Employees] table like this
EmployeeID FirstName LastName PhotoPath
---------- --------- -------- ---------------------------------
1 Gord Thompson C:\Users\Public\Pictures\Gord.jpg
2 Hank Kingsley C:\Users\Public\Pictures\Hank.png
you could use an Image control whose Control Source is the [PhotoPath] field ...
... and the image will automatically be retrieved from the file specified
No VBA required.
Note also that the image files do not have to be .bmp files.
Added by an anonymous user:
For users of the Microsoft Office 365 version of MS Access (c. 2020), here is what you may need to know in order to get this terrific solution to work:
The [PhotoPath] field in its data table needs to be "Long Text" data type, if using long paths or long file names. The [PhotoPath] field format "Is Hyperlink" may need to be set to "No." I was getting additional, unwanted coding from Access on my text inputs. The [Image3] control may need to specify "Linked" rather than "Embedded."
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 )