Access VBA reserved word "name" - vba

I am using Access VBA to access movie information using the API. It is working fine but I have a problem with attributes that have as name the word "name" which is a reserved word.
Let's say I want to access the production companies. I am using this code, and it is working fine if I want to get the id, but it doesn't work if I am trying to get the names because the word "name" is a reserved word in line 4.
Does anyone have an idea how to fix it?
The working code:
Set Keys1 = VBA.CallByName(jsonDecode1, "production_companies", VbGet)
movie_companies = ""
For Each Key In Keys1
movie_companies = movie_companies & **key.id** & ","
Next
The not working code:
Set Keys1 = VBA.CallByName(jsonDecode1, "production_companies", VbGet)
movie_companies = ""
For Each Key In Keys1
movie_companies = movie_companies & **Key.Name** & ","
Next
The json file:
production_companies: [ { name: "France 2 Cinéma", id: 83 }, { name: "SBS Productions", id: 8997 }, { name: "Les Films Français", id: 16782 } ],
Thank you for your reply, but i need to give you more details of what i am doing. yes i am using a collection but i didn't create it i am just importing data do the collection from a website using API, also i want to let you know that all the other properties works fine except the "name" may be because the editor capitalize the first letter of the word "Name" automatically but it doesn't capitalize the other words, how can i avoid the editor to capitalize the word "name" maybe that's the issue. Thank you again
That's the whole code:
Set sc = CreateObject("ScriptControl"): sc.language = "JScript"
Set oXMLHTTP1 = CreateObject("MSXML2.XMLHTTP")
oXMLHTTP1.Open "GET", URL, False 'Open socket to get the website
oXMLHTTP1.setRequestHeader "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"
oXMLHTTP1.send 'send request
Do While oXMLHTTP1.ReadyState <> 4
DoEvents
Loop
oResp = oXMLHTTP1.responseText 'Returns the results as a byte array
Set jsonDecode1 = sc.Eval("(" + oResp + ")")
Set Keys1 = VBA.CallByName(jsonDecode1, "production_countries", VbGet)
For Each Key In Keys1
movie_companies = movie_companies & Key.id & ","
movie_companies = movie_companies & Key.Name & ","
Next
Now i am sure that the problem is the fact that the first letter is uppercase, because i have another property named "key" and because the editor change it to "Key" with uppercase K, it is not working too :) is there a way to disabled changing the first letter to uppercase in the code editor? this will definitely fix the problem

I fixed it :), it is weird but i fixed it.
what you need to do is declare a variable "name" with the lower case "n" and after that i remove it and now the code editor don't capitalize the word "name" anymore. If i declare a variable with the first letter capital it will save it and even if i remove the declaration the next time you use it it will automatically capitalize it and you cannot remove until you declare it again with all lower :)
Thank you all

From what I can see, this has ZERO to do with reserved words.
The use of name is a valid property of a GAZILLION built in objects such as forms, reports, column names pulled from a record set etc.
The “conflict” of reserved words is ONLY in regards to SQL or using VBA variables you define (and name is in fact NOT a reserved word anyway).
You are using “someobject.Name” and thus this has ZERO to do with reserved words since a property or method of an object called “name” NEVER was a source of errors or issues in Access VBA. In fact built in methods can use reserved words.
Ignoring that you left out the data type of this function? (cannot stress how you want to code with option explicit and ALSO cannot stress how you should give a data type to that function).
However I shall make a BIG guess and assume it is a VBA collection object.
Collections in VBA don’t have a name property. So this works:
Dim c As New Collection
c.Add "Apple", "testkey1"
c.Add "Grape", "testkey2"
Dim f As Variant
For Each f In c
Debug.Print f
Next
However f.name will fail since “.name” is NOT a property or method of a collection. So this issue has nothing to do with reserved words but the simple fact that “.name” never been part of or a valid syntax for a collection object.
And if you really do need each element of the collection to have values, then your function can return a collection of “structures” but that structure will have to be a class object. So this code shows this in Action:
So the class module can be:
Class module clsStruct:
Option Compare Database
Option Explicit
Public Name As String
Public KeyName As String
Public Value As String
Now in our code:
Dim c As New Collection
Dim MyStruct As New clsStruct
MyStruct.KeyName = "hello"
MyStruct.Name = "myname"
MyStruct.Value = "my value"
c.Add MyStruct
Dim f As Variant
For Each f In c
Debug.Print f.Name, f.Value, f.KeyName
Next
Output:
myname my value hello
So you are MOST free to use “.name” as a valid property of a object you create, but the collection object by default has no such name property and thus will fail at runtime.

Related

How to refer to Word Field by name in VBA Code?

I want to update a word field content using VBA. I already have a code that works, but I have to refer to the field's index instead of field's name, which I would prefer.
The code I have is as follows:
Sub UpdateField()
Dim myString As String
myString = "asdf"
ActiveDocument.Fields(1).Result.Text = myString
End Sub
Suppose that the field's name is MyField1. The following code will not work (I get the Run-time error '13': Type mismatch'.
Sub UpdateField()
Dim myString As String
myString = "asdf"
ActiveDocument.Fields("MyField1").Result.Text = myString
End Sub
I create my word fields from File Menu > Informations > Advanced Properties > Custom Tab.
So, how to refer to the field's name when we want to update its content?
These are DocProperty fields. If you press Alt+F9 you'll see the field codes.
A DocProperty field references (links to) a Document Property. The Document Property has the name, but this does not "name" the field. Nor is it possible to update a DocProperty field directly since it links to the Document Property. It might be possible to make it temporarily display something else, but this will be lost any time the field is updated.
In order to update a DocProperty field it's necessary to update the underlying Document Property. For example
Sub EditDocPropUpdateDocPropertyField()
Dim doc As Word.Document
Dim prop As Office.DocumentProperty
Dim propName As String
Dim newPropValue As String
Set doc = ActiveDocument
propName = "MyField"
newPropValue = "new value"
Set prop = doc.CustomDocumentProperties(propName)
prop.value = newPropValue
doc.Fields.Update
End Sub
In the VBE, the Object Browser is a great way to find out what's possible. When I find Word>Field and click on it, I see a list of the members of Field. Name is not in that list. This means that the field object does not have a Name property. That's why you get the error.
You can work around this. One way is to create a bookmark around the field in question. Then in code, find the bookmark by name, then find the field by index inside the bookmark range.
Sample to set text to fields by field name:
ThisDocument.FormFields.Item("MyField1").Result = "hello"

How do I get only one result for each app instead of double?

Copy this into Visual Studio, add a textbox and it'll run.
Const NET_FW_ACTION_ALLOW = 1
Dim fwPolicy2 = CreateObject("HNetCfg.FwPolicy2")
Dim RulesObject = fwPolicy2.Rules
For Each rule In RulesObject
If rule.action = NET_FW_ACTION_ALLOW Then
TextBox1.Text += rule.name & vbnewline
End If
Next
This is an example of what I get but I only need each app to be listed once, not two times. What am I doing wrong or why does it behave like this?
qBittorrent
qBittorrent
Chrome
Chrome
Visual Studio
Visual Studio
and so on...
It behaves like this because rule.Name is not a unique identifier for a firewall rule. The same rule name may be used for different protocols (TCP, UDP), profiles (domain, private, public), direction (in, out), etc. If you are only interested in rule.Name, add them to a set, then print that set, as follows.
Const NET_FW_ACTION_ALLOW = 1
Dim fwPolicy2 = CreateObject("HNetCfg.FwPolicy2")
Dim RulesObject = fwPolicy2.Rules
Dim names As New HashSet(Of String)
' Create set of unique names.
For Each rule In fwPolicy2.Rules
If rule.action = NET_FW_ACTION_ALLOW Then
names.Add(rule.name)
End If
Next
' Add names to TextBox.
For Each name As String In names
TextBox1.Text += name & vbNewLine
Next
For Each rule In RulesObject
If rule.action = NET_FW_ACTION_ALLOW AndAlso TextBox1.Text.Contains(rule.name.ToString) = False Then
TextBox1.Text += rule.name & vbnewline
End If
Next
The above is one way to do it. It simply checks whether it's already added to the textbox. Btw, I don't know offhand whether or not rule.name is already a string so I added .ToString; if it's already a string, you don't need to add that.
Also, most of us would recommend using Option Strict, and declaring your variables as a type. i.e. Dim myVar as String = "some string"

Create an appointment with required attendees in Lotus Notes using VBA in Access 2013

I am attempting to create a check out log for inventory in Access 2013. During this process you will create an appointment on the expected return date in the Lotus Notes 9 calendar. I have found enough examples to do this successfully. However I am getting stuck when trying to add people to the "RequiredAttendees" field. I am pretty sure that I am using the right field name but i keep getting the following error:
Run-time error '-2147417851 (80010105)': Automation error. The server
threw an exception.
Everything else works fine except the part that tries to add attendees. I know Lotus Notes 9 is old and I know Access 2013 is old but those are the tools I am required to work with. Any help would be appreciated.
Public Function test() As Variant
Dim StartTime As Date
Dim MailDbName As String
Dim CalenDoc As Object
Dim WorkSpace As Object
Dim AppDate As String
Dim AppTime As String
Dim Subject As String
Set WorkSpace = CreateObject("Notes.NOTESUIWORKSPACE")
AppDate = InputBox(Prompt:="Enter the return date:")
'Subject = InputBox(Prompt:="Enter the subject:")
'AppTime = InputBox(Prompt:="Enter the time:")
MailDbName = "mail\User.nsf"
strSTime = CStr(Timex)
Set CalenDoc = WorkSpace.COMPOSEDOCUMENT("MailServer", MailDbName, "Appointment")
CalenDoc.FIELDSETTEXT "AppointmentType", "3"
CalenDoc.Refresh
CalenDoc.FIELDSETTEXT "StartDate", CStr(AppDate)
CalenDoc.FIELDSETTEXT "EndDate", CStr(AppDate)
CalenDoc.FIELDSETTEXT "StartTime", "12:00 PM"
CalenDoc.FIELDSETTEXT "EndTime", "12:00 PM"
CalenDoc.FIELDSETTEXT "Subject", "Test"
GetUser = Environ("UserName")
EmailAddress = GetUser & "#company.com"
If EmailAddress = "User1#company.com" Then
CalenDoc.FIELDSETTEXT "RequiredAttendees", "User2#company.com" & "," & "User3#company.com"
CalenDoc.Refresh
ElseIf EmailAddress = "User2#company.com" Then
CalenDoc.FIELDSETTEXT "RequiredAttendees", "User1#company.com" & "," & "User3#company.com"
CalenDoc.Refresh
ElseIf EmailAddress = "User3#company.com" Then
CalenDoc.FIELDSETTEXT "RequiredAttendees", "User2#company.com" & "," & "User1#company.com"
CalenDoc.Refresh
Else
MsgBox (EmailAddress & "is not a valid email address.")
End If
'CalenDoc.gotoField "Body"
'CalenDoc.InsertText Body
CalenDoc.Refresh
'CalenDoc.Save
'CalenDoc.Close
'Set CalenDoc = Nothing
'Set WorkSpace = Nothing
I think you've been confused by looking at examples that use the back-end COM classes instead of, or maybe in addition to, examples that use the front-end OLE classes. You are using Notes.NOTESUIWORKSPACE - OLE, instead of Lotus.NotesSession - COM. That means you have to use the actual editable fields on the Appointment form, which are sometimes not what you expect them to be. In some cases, these front-end fields are not the same as the items that will end up being stored in the back-end document - and it's the back-end item names that are typically documented because they are the ones that get stored in the note.
RequiredAttendees is the stored item name, but you are getting the automation error because it's a computed field on the Appointment form, not an editable field.
Since you are using OLE, you need to enter the data into the "EnterSendTo" field. The data that you (or a user) puts in there will, in fact, end up in the RequiredAttendees item due to the magic that goes on in the formulas and scripts associated with the Appointment form.

Find and Replace specific string in Outlook message

My code basically searches for the string "#XX" in the email body. The "#XX" is usually followed by a text like "#XXApple". And this "#XXApple" can be seen multiple times in the email message.
The code below works in such a way that it only replaces the first hit with spaces. However, the rest of the "#XXApple" will only be changed to "Apple"
Is there a way where I can do a "Find and Replace All" in Outlook?
obj.HTMLBody = Replace(obj.HTMLBody, "#XX", " ", 15)
Not tested or verified but this is the general idea of what I meant to say in the comment above.
Dim Cet
Dim TesPos As Int, i As Int
Cet = Split(obj.HTMLBody, " ")
For i=LBound(Cet) to Ubound(Cet)
TestPos = 5
TestPos = InStr(1,Cet(i), "#XX", CompareMethod.Text)
if TestPos = 1 then
Cet(i) = ""
Else: End if
Next i
obj.HTMLBody = ""
For i=LBound(Cet) to Ubound(Cet)
obj.HTMLBody = obj.HTMLBody & " " & Cet(i)
Next i
Debug.Print obj.HTMLBody
The Outlook object model provides three main ways for working with item bodies:
Body - a string representing the clear-text body of the Outlook item.
HTMLBody - a string representing the HTML body of the specified item.
Word editor - the Microsoft Word Document Object Model of the message being displayed. The WordEditor property of the Inspector class returns an instance of the Document class from the Word object model which you can use to set up the message body.
You can read more about all these ways in the Chapter 17: Working with Item Bodies. It us up to you which way is to choose to deal with the message body. But the Word object model provides all the required methods to get the job done.

How do you correctly set document properties using VBA?

The problem
I'm having some trouble setting document properties using VBA in Word 2010.
I have a document containing several Heading 1 sections and I use a macro to extract a selected section (along with it's contents) and paste it to a new document.
This part works fine, but at the end I need to set several document properties, but none of them are being set.
I'm trying to set both built-in and custom properties, but for the purpose of this question I'd like to set title, subject and, category.
I've created a function to set the properties I desire (as below), and VBA is throwing no error (even when I remove error handling in the function).
Does anybody know what I am doing wrong?
How the function should work
Here is a brief summary of what the function should do, but the full function is below should you find it easier to check that -
Check to see if the property already exists
It does and it is a default property
Set the default property
Set the PropertyTypeUsed variable to default
it does and it is a custom property
Set the custom property
Set the PropertyTypeUsed variable to custom
It does not exist at all
Create a new custom property
Set the custom property
Set the PropertyTypeUsed variable to custom
Check whether or not a value has successfully been set
A default property should have been set
Was the property set successfully?
A custom property should have been set
Was the property set successfully?
Return the result
The function I believe is causing the issue
Function UpdateDocumentProperty(ByRef doc As Document, _
ByVal propertyName As String, _
ByVal propertyValue As Variant, _
Optional ByVal propertyType As Office.MsoDocProperties = 4)
'** Set the result to 'False' by default '*
Dim result As Boolean
result = False
'** A property to hold whether or not the property used is default or custom *'
Dim propertyTypeUsed As String
'** Check to see if the document property already exists *'
If PropertyExists(doc, propertyName) Then ' A default property exists, so use that
doc.BuiltInDocumentProperties(propertyName).value = propertyValue
propertyTypeUsed = "default"
ElseIf PropertyExists(doc, propertyName, "custom") Then ' A custom property exists, so use that
doc.CustomDocumentProperties(propertyName).value = propertyValue
propertyTypeUsed = "custom"
Else ' No property exists, so create a custom property
doc.CustomDocumentProperties.Add _
name:=propertyName, _
LinkToContent:=False, _
Type:=propertyType, _
value:=propertyValue
propertyTypeUsed = "custom"
End If
'** Check whether or not the value has actually been set *'
On Error Resume Next
If propertyTypeUsed = "default" Then
result = (doc.BuiltInDocumentProperties(propertyName).value = propertyValue)
ElseIf propertyTypeUsed = "custom" Then
result = (doc.CustomDocumentProperties(propertyName).value = propertyValue)
End If
On Error GoTo 0
UpdateDocumentProperty = result
End Function
Full project code
The full code for this project can be found in two Paste Bins -
The functions
The form
I'm not sure if it's possible to get the code for actually creating the form (short of exporting it, but I have no where to put it), but in any case it's very simple -
The form - frmChooseDocument
The label - lblChooseDocument (Which New Starter document would you like to export?)
The combobox - comChooseDocument
The cancel button - btnCancel
The OK button - btnOK (Initially disabled)
In reality I'm using the document that houses this code as a 'master' document for new startes, containing detailed instructions on how to use variouse applications.
The code itself looks for Heading 1 formatted text within the document and adds them to the combobox in the form, allowing the user to select a section to export. A new document is then created and saved as a PDF.
Update
As suggested in the comments, I have checked that the type of value being set matches that of the value being passed to the function and it does.
In the case of all 3 properties described above, both the value that I am passing and the property as stored against the document are of type string.
I've added a couple of lines to output the type and value where I am setting the result and all looks well, but obviously it is not!
Debug.Print "My value: (" & TypeName(propertyValue) & ")" & propertyValue
Debug.Print "Stored property: (" & TypeName(doc.BuiltInDocumentProperties(propertyName).value) & ")" & doc.BuiltInDocumentProperties(propertyName).value
Here is the output -
My value: (String)New Starter Guide - Novell
Stored property: (String)New Starter Guide - Novell
My value: (String)New starter guide
Stored property: (String)New starter guide
My value: (String)new starters, guide, help
Stored property: (String)new starters, guide, help
I managed to set my word document title by saving the document after changing the property. I set the "Saved" property to false first to make sure that Word registers the change in state.
Function ChangeDocumentProperty(doc As Document, sProperty As String, sNewValue As String)
Debug.Print "Initial Property, Value: " & sProperty & ", " & doc.BuiltInDocumentProperties(sProperty)
doc.BuiltInDocumentProperties(sProperty) = sNewValue
doc.Saved = False
doc.Save
ChangeDocumentProperty = (doc.Saved = True And doc.BuiltInDocumentProperties(sProperty) = sNewValue)
Debug.Print "Final Property, Value: " & sProperty & ", " & doc.BuiltInDocumentProperties(sProperty)
End Function
Immediate Window:
? ThisDocument.ChangeDocumentProperty(ThisDocument, "Title", "Report Definitions")
Initial Property, Value: Title, Report Glossary
Final Property, Value: Title, Report Definitions
True
Permanent object properties cannot be set by functions. In other words, VBA does not allow functions to have side effects that persist after the function is finished running.
Re-write the function as a Sub and it should work.