How to pass KM Variable into a Word Mac 2011 Macro (as a Variable)?

How do I pass a KM Variable into a Word Mac 2011 Macro and use it there as a variable?

Thanks in advance.

Great question! I too would like to know the answer.

Here’s an idea: Call an AppleScript from Word VBA, or if possible, do a shell script from VBA to get the KM var.

1 Like

Hey Steve,

I don’t use VBA in Word, so my advice is inexpert in this area.

However – because of the way Keyboard Maestro interacts with the shell I don’t think calling the shell from VBA will access the KM environment’s variables.

It might be possible to save a document variable with AppleScript and then access that from VBA.

I’m thinking the most likely solution is writing your value(s) to a file with KM and then reading them from VBA – but do let us know if you figure out something more clever.

-Chris

1 Like

Bingo!

Pseudo Code

Get KM Variable
Set Word Doc variable to this
Run VB macro that uses this variable

Chris, I'm almost there, but need your help with the below error.
I can get the list of variables in the Word doc, but I can't get the specific variable I want. It's in the list, I just can't get it out!

##example AppleScript


--set strFilePath to (choose file) as text
--log strFilePath

tell application "Microsoft Word"
	--set oDoc to open file name strFilePath
	
	set lstVars to variables of active document
	log lstVars
	--> (*variable KMVar2 of active document, variable KMVar3 of active document*)
	
	set lstVar2 to every variable of active document
	log lstVar2
	--> (*variable KMVar2 of active document, variable KMVar3 of active document*)
	
	--- THIS WORKS TO CREATE AND SET A NEW VARIABLE ---
	make new variable at active document ¬
		with properties {name:"KMVar2", variable value:"Set by AppleScript"}
	
	set oVar to item in lstVars whose name is "KMVar2" # <=== This FAILS with:
	(*
	error "Can’t get item of {variable \"KMVar2\" of active document of application \"Microsoft Word\", variable \"KMVar3\" of active document of application \"Microsoft Word\"}." number -1728 from item of {«class w112» "KMVar2" of «class 1003», «class w112» "KMVar3" of «class 1003»}
	*)
	
	log oVar
	
	set strName to name of oVar
	log strName
	
end tell

For reference, here is the post/script I got this from, that includes running the VBA macro from AppleScript:

Can I pass parameters to a Word 2011 macro, from applescript?

on run {param1}
  tell application "Microsoft Word"
    activate
    open (path to home folder as string) & "Documents:Seminar Pro:Templates:test.dotm"
    make new variable at active document ¬
      with properties {name:"FullName", variable value:param1}
    run VB macro macro name "NewMacros.testArguments"
  end tell
end run

####VBA Sub to Use Doc Variable:

Sub testArguments()

MsgBox ActiveDocument.Variables("FullName").Value
ActiveDocument.Variables("FullName").Delete

End Sub

OK, I figured out how to get and existing Word document variable.

the key was:

set oVar to first item in lstVar -- Get the Record out of the List

####Here's the working code:
I commented out the lines to select and open the Word document for testing purposes. The doc was already open for this script.
You just need to add the code for:

  1. Get the KM Variables in AppleScript (See several posts below for code by @ccstone)
  2. Run the VBA Macro

####EDIT #3: Wed, Dec 16, 2015 at 6:36 PM
Please see/use my final code posted below at:


####Original Code

--set strFilePath to (choose file) as text
--log strFilePath

tell application "Microsoft Word"
	--set oDoc to open file name strFilePath
	
	set strVarName to "KMVar3" -- VBA Document Variable that corresponds to KM Variable
	set strVarValue to "Set by AppleScript on " & ((current date) as string) -- Replace with KM Var value
	
	--- GET THE LIST RECORD FOR THE DESIRED VARIABLE ---
	set lstVar to variables of active document whose name is strVarName
	
	if lstVar is missing value then -- the Variable didn't exist
		
		--- CREATE NEW DOC VARIABLE AND SET THE VARIABLE VALUE TO THE KM Variable value ---
		make new variable at active document with properties {name:strVarName, variable value:strVarValue}
		set strName to strVarName
		set strValue to "<Variable Didn't exist>"
		
	else --- SET NEW VALUE FOR EXISTING VARIABLE ---
		
		set oVar to first item in lstVar -- Get the Record out of the List
		set strName to name of oVar
		set strValue to variable value of oVar
		log oVar
		
		--- UPDATE THE VBA Variable Value ---
		set variable value of oVar to strVarValue
		
	end if
	
	log ("OLD Value of " & strName & ": " & strValue)
	log ("NEW Value of " & strName & ": " & strVarValue)
	
	
end tell

Hey JM,

I think you're doing that the hard way.

------------------------------------------------------------
tell application "Microsoft Word"
  
  # --- THIS WORKS TO CREATE AND SET A NEW VARIABLE ---
  # make new variable at active document ¬
  #   with properties {name:"KMVar2", variable value:"Set by AppleScript"}
  
  tell active document
    # Run each of these lines separately to see what they do.
    # This sort of progression is how you learn about the object in question.
    variables
    properties of variables
    variable value of variable "KMVar2"
    
    # Now we've learned how to use it.
    set myNewVar to variable value of variable "KMVar2"
    
  end tell
  
end tell
------------------------------------------------------------

-Chris

Hey JM,

You don’t want a run-handler with parameters.

on run {param1}
  # Body
end run

This is undesirable unless you’re running the script from another script.

Basically there’s no point in EVER having a formal run-handler unless you also have other “on activation” handlers like on open.

A run-handler will operate when the script is run.

An open-handler will operate when items are dragged and dropped onto a script-applet.

An applet can have both run and open handlers.

-Chris

Of course you do! You always do! :grin:

But it really wasn't that hard.
Yours is marginally better. :astonished:

But mine works, and it runs fast.
So does it really matter?

I searched and found no examples or documentation like the approach you used. But then you've been using AppleScript at least 10X as long as I have. LOL

Thanks as always for your great insights.

Actually, you didn't set nor create a VBA Doc variable.
My code does both. ha ha ha :sunglasses:

Yes, and I'm working off of your code. :smile:

OK, showoff, why don't you show the OP how to get the KM var in AppleScript? :wink:

[quote=“JMichaelTX, post:9, topic:2582”]But mine works, and it runs fast.So does it really matter?/quote]

Hey JM,

Suppose you have 50 variables? Do you really want to try to manage them by position or otherwise piecemeal?

tell application "Microsoft Word"
  tell active document
    name of variables
  end tell
end tell

It’s a whole lot easier to work with variables by name:

tell application "Microsoft Word"
  tell active document
    if not (variable "KMVar1" exists) then
      make new variable at it with properties {name:"KMVar1", variable value:"Set by AppleScript"}
    else
      set myVarName to variable value of variable "KMVar1"
    end if
  end tell
end tell

-Chris

Actually I wasn't doing that.

I have two lines of code:

set lstVar to variables of active document whose name is strVarName
set oVar to first item in lstVar -- Get the Record out of the List

for your one line:

tell active document to set oVar to variable strVarName

My first line gets ONLY the desired variable by name, but it is in a list, whereas yours gets the variable directly.
Getting the "first item" is get the one and only item in that list.

Not that much different, IMO.

####IAC, here's my code updated with your approach, FWIW:
I left my code there for visibility, just commented it out.

####EDIT: Wed, Dec 16, 2015 at 6:33 PM
I have removed my code because it fails due to a bug in the Word AppleScript interface.

See my corrected/final code below at:

Hey JM,

This is actually new and improved in KM 7.0.2. (REQUIRES Keyboard Maestro 7.0.2)

####Set Keyboard Maestro variable using AppleScript.

---------------------------------------------------------------------
# Keyboard Maestro — Set value of variable "<variable name>"
---------------------------------------------------------------------
set myText to "whatever"

tell application "Keyboard Maestro Engine"
  if variable "myKMVariableName" exists then
    set value of variable "myKMVariableName" to myText
  else
    make new variable with properties {name:"myKMVariableName", value:myText}
  end if
end tell
---------------------------------------------------------------------

####Get Keyboard Maestro variable using AppleScript.

---------------------------------------------------------------------
# Keyboard Maestro — Get value of variable "<variable name>"
---------------------------------------------------------------------
tell application "Keyboard Maestro Engine"
  if variable "myKMVariableName" exists then
    set myAppleScriptVariableName to value of variable "myKMVariableName"
  end if
end tell
---------------------------------------------------------------------

-Chris

1 Like

Great! Thanks.

May I suggest that you put this in the KM Wiki?

Hey JM,

Oops. Missed that.

Still you're not going to have more than one variable with the same name, so why not save a step.

One way your approach might become more relevant is if you need to list more than one variable with similar names:

tell application "Microsoft Word"
  tell active document
    variables whose name contains "KM"
  end tell
end tell

OR

tell application "Microsoft Word"
  tell active document
    tell (variables whose name contains "KM")
      set varNameList to name
      set varValueList to variable value
    end tell
  end tell
end tell

-Chris

2 Likes

I agree. My only point is that my code wasn't really that different.
But no need to use two statements when one will do.

And your approach is very clear:
tell active document to set oVar to variable strVarName

It's very readable and obvious what that is doing.

Microsoft could haved save me, and I'm betting many others, a lot of work and time if they would have included some simple examples in their AppleScript Dictionary.

But, I learned a lot today, and that's always a good thing. :+1:

Chris, did you test this?

I'm finding that it always returns true, even when the variable does not exist.

My test code:

tell active document
	if (variable strVarName exists) then
		display dialog strVarName & " EXISTS"
	else
		display dialog strVarName & " Does NOT exist"
	end if
end tell

Hey JM,

Wow, that's nasty. I'll get back to you in a bit.

-Chris