Jump to content
Sign in to follow this  
water

Set property of an object passed as variable

Recommended Posts

water

How can I set the value of a property by passing the property name as variable? Like:

$sPropertyName = "Username"
$oWord_Appl.Username = "Test" ; Works
$iResult = Assign("oWord_Appl.Username", "Test", 4) ; Returns 0: unable to create/assign the variable
$iResult = Assign("oWord_Appl." & sPropertyName, "Test", 4) ; Returns 0: unable to create/assign the variable
Is it possible at all? If yes, how?

Thanks in advance!


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
stormbreaker

Water, I think you should declare $OWord_Appl first, like:

Global $OWord_Appl

I read through Assign example and the variables to be used were declared first.

Good luck...


----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Share this post


Link to post
Share on other sites
water

Variable $oWord_Appl is already declared and is set to the Word application object. I would like to set a property of this object by passing the name to a function. This way I can keep the function flexible and don't have to list all valid properties in the function. If a new version of Microsoft Word adds new properties my function needs not to be changed.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
stormbreaker

Assign function requires the variable to be declared(do a forum search and you will get it, its an old thread of around 2008), so, if its a property value, may be you could try something like:

Global $myvar

Local $myvar.property

;your assign function goes now


----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Share this post


Link to post
Share on other sites
water

MKISH,

my problem is not with the $myvar part but with "property". Example:

Global $oWord_Appl
Set_Property($oWord_Appl, "Username", "Test")
Func Set_Property($oObject, $property, $value)
    $oObject.$property = $value ; <== How to write this line?
EndFunc
Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
stormbreaker

Water, taking my example, I would write the assign function as:

Assign('myvar.property', 'value', 4)


----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Share this post


Link to post
Share on other sites
water

MKISH,

If you have Microsoft Word installed then here is a small reproducer script to show you what I need. The problem is that the name of the property I need to change is passed as parameter to the function.

Global $oWord_Appl = ObjGet("", "Word.Application")
If @error Then
    $oWord_Appl = ObjCreate("Word.Application")
    If @error Then Exit MsgBox(16, "Word property", "Error starting Word!")
EndIf
_ChangeUsername($oWord_Appl, "Username", "Test")
$oWord_Appl.Quit()
Exit

Func _ChangeUsername($oAppl, $sProperty, $sValue)
    MsgBox(64, "Word property", 'Current value of Word application property "Username": ' & $oWord_Appl.Username)
    Local $iResult = Assign($oAppl.$sProperty, $sValue, 4) ; <==== This statement needs to be changed to make it work!
    If $iResult = 1 Then
        MsgBox(64, "Word property", 'New value of Word application property "Username": ' & $oWord_Appl.Username)
    Else
        MsgBox(16, "Word property", "Could not set $oAppl.UserName!")
    EndIf
    Return
EndFunc

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
stormbreaker

What I get now is that you are trying to somehow convert '$object' to 'object' so that you can use it with assign function. Right?

I think you could try using assign function without the flag value 4. Flag 4 requires that your variable is declared (using local or global statements)

func assigntoword($property, $value)

Assign('oAppl.' & $property, '' & $value)

endfunc

;don't use flag here and try if it works, sorry i am currently travelling


----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Share this post


Link to post
Share on other sites
hannes08

I tried what both of you wrote and I even fail with only getting properties:

#include <word.au3>
Global $oWord_Appl
$oWord_Appl = _WordCreate()
ConsoleWrite(Get_Property($oWord_Appl, "Username") & @CRLF)
Func Get_Property($oObject, $property)
    Local $str = "oObject." & $property
    Local $result = Execute($str)
    Local $err = @error
    ConsoleWrite($str & @CRLF)
    ConsoleWrite($result & @TAB & $err & @CRLF)
    Return $result
EndFunc

So I'm not sure that you can get it to work anyhow, but maybe if you findout how to read the properties you can also find out how to write the properties.

@MKISH, I don't think the issue is with declarations of variables here...

Edited by hannes08

Regards,Hannes[spoiler]If you can't convince them, confuse them![/spoiler]

Share this post


Link to post
Share on other sites
trancexx

MKISH,

If you have Microsoft Word installed then here is a small reproducer script to show you what I need. The problem is that the name of the property I need to change is passed as parameter to the function.

Global $oWord_Appl = ObjGet("", "Word.Application")
If @error Then
    $oWord_Appl = ObjCreate("Word.Application")
    If @error Then Exit MsgBox(16, "Word property", "Error starting Word!")
EndIf
_ChangeUsername($oWord_Appl, "Username", "Test")
$oWord_Appl.Quit()
Exit

Func _ChangeUsername($oAppl, $sProperty, $sValue)
    MsgBox(64, "Word property", 'Current value of Word application property "Username": ' & $oWord_Appl.Username)
    Local $iResult = Assign($oAppl.$sProperty, $sValue, 4) ; <==== This statement needs to be changed to make it work!
    If $iResult = 1 Then
        MsgBox(64, "Word property", 'New value of Word application property "Username": ' & $oWord_Appl.Username)
    Else
        MsgBox(16, "Word property", "Could not set $oAppl.UserName!")
    EndIf
    Return
EndFunc

water that code is lame.

Could you show what exactly you want to do? Why would you need such function?


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
water

... but maybe if you find out how to read the properties ...

Reading the properties is "easy" ;)

$sProperty = Execute("$oWord_Appl." & $sProperty)
You missed the $ sign.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
water

trancexx, thanks for replying.

I'm about to rewrite function _WordPropertySet. You can pass a single property name as parameter.

The Word application object has no collection for all properties so you have to access them by name.

The function compares the parameter with all the properties it can set. If a match is found the appropriate property is set.

This leads to a lot and unflexible code. You can not process all possible properties now - only those defined in the function.

Something like:

Switch $s_Property
    Case "activeprinter"
        $o_object.Application.ActivePrinter = $v_newvalue
    Case "screenupdating"
        $o_object.Application.ScreenUpdating = $v_newvalue

Imagine a new Word version offers new properties. The function has to be changed to process them.

If the name of the property could be replaced by the parameter the function could be reduced to a few lines and would be flexible enough for future changes of Word.

I hope I could make myself clear ;)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
trancexx

trancexx, thanks for replying.

I'm about to rewrite function _WordPropertySet. You can pass a single property name as parameter.

The Word application object has no collection for all properties so you have to access them by name.

The function compares the parameter with all the properties it can set. If a match is found the appropriate property is set.

This leads to a lot and unflexible code. You can not process all possible properties now - only those defined in the function.

Something like:

Switch $s_Property
    Case "activeprinter"
        $o_object.Application.ActivePrinter = $v_newvalue
    Case "screenupdating"
        $o_object.Application.ScreenUpdating = $v_newvalue

Imagine a new Word version offers new properties. The function has to be changed to process them.

If the name of the property could be replaced by the parameter the function could be reduced to a few lines and would be flexible enough for future changes of Word.

I hope I could make myself clear ;)

Paradigms in collision.

_WordPropertySet shouldn't exist at all. Mindset needs changed. Objects should be used as intended.

Really, I have changed AutoIt internally a whole lot for it to give the user a proper interface for object manipulation. Use it.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
water

Thanks, function will be removed.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • FrancescoDiMuro
      By FrancescoDiMuro
      Good evening everyone
      I'm working on a little project of mines, and I was trying to use WMI Object.
      The question which I don't find an answer is: 
      Once I do the query with WMI Object, something like "SELECT * FROM Win32_LogonSession", instead of specify the field of the collection returned, ( i.e. $colItems.Caption ), can I loop though each property and each value of the property, writing so one row of code only?
      Hope my question was clear enough.
      Thanks in advance.

      Best Regards.
    • Fenzik
      By Fenzik
       Hello all"
      I have curious problem with com object implementation of Sapi 5.1.
      In some cases }Some Voice engines] the metods for retrieve the voice parameters fails with error :Member not exists:.
      But the Retrieved Voice object can speak the given text, so It exists and work.
      Example of this type of Engine can be this one: http://download.kobavision.be/KobaSpeech3/KobaSpeech 3 With Vocalizer Serena - English (Great Britain).exe (can work as demo)
      So my question is> Is there some way to workaround or solve this issue?
      What i tryed:
      1. Typical use of Sapi.spvoice object:
      $oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler
       
        $spvoice = ObjCreate("sapi.spvoice")
      for $voice in $spvoice.getvoices()
        msgbox(0, "Voice", $voice.getdescription())
      next
      Func MyErrFunc()
      $HexNumber = hex($oMyError.number, 8)
      Msgbox(0,"","We intercepted a COM Error !" & @CRLF &"Number is: " & $HexNumber & @CRLF &"Windescription is: " & $oMyError.windescription)
      SetError(1)
      Endfunc

      2. Implement workaround based on Nvda Screen reader sapi5 Library at https://github.com/nvaccess/nvda/blob/master/source/synthDrivers/sapi5.py
      Thys code in Pascal should work, so i tryed to reproduce it in Autoit.
      Pascal code just as example:
                   SOTokens:=SpVoice.GetVoices('','');
                   for i:=0 to SOTokens.Count-1 do
                   try
                        SOToken:=SOTokens.Item(I); s:=SOToken.GetDescription(0);
      end
      In Autoit I tryed it like this:
      $oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler
        $spvoice = ObjCreate("sapi.spvoice")
      for $i = 0 to $spvoice.getvoices.count-1
      $name = $spvoice.getvoices.item($i).getdescription
      msgbox(0,"Voice", $name)
      next
      Func MyErrFunc()
      $HexNumber = hex($oMyError.number, 8)
      Msgbox(0,"","We intercepted a COM Error !" & @CRLF &"Number is: " & $HexNumber & @CRLF &"Windescription is: " & $oMyError.windescription)
      SetError(1)
      Endfunc
      Both of this methods returning same Error ("Member not exists.").
      Thanks a lot for help.
      Znefyg
    • SchneiMi
      By SchneiMi
      Hello,
      following my previous question, I have moved all potentially instable object interactions into Executes. But it Looks like "="-assignments to object Attributes cannot be done with Execute, only method calls. Using an "$obj = 1" construct, it compares (Eval) instead of sets (Execute) the value.
      I have tested multiple different combinations, using Execute and Assign, but it seems not to work with object Attributes. :-(
      Gives following Output:
      The assign Action using apply (a3) Fails, while assigning it directly, without Assign() works fine.
      The execute versions compare and do not assign, in both cases. Though, the "Execute" topic in the help file says it executes, not evaluates.
      I have found a similar, old thread, which explains this behavious but does not give a solution. https://www.autoitscript.com/forum/topic/110228-pass-object-property-as-a-variable/  
      Is there a way to assign to a com object's Attribute? Or is there anything new to this unexpected behaviour of Execute (at least compared to the help file description and Python's exec).
       
      Any help is appreciated, and thank you for all the help so far.
      Regards, Michael
       
    • Simpel
      By Simpel
      Hi,
      since some days I become this error message exiting my app:

      Eventviewer shows following data:
      Name der fehlerhaften Anwendung: autoit3.exe, Version: 3.3.14.2, Zeitstempel: 0x55fc1979 Name des fehlerhaften Moduls: ntdll.dll, Version: 6.1.7601.23864, Zeitstempel: 0x595fa490 Ausnahmecode: 0xc000000d Fehleroffset: 0x000987e0 I stripped my code from 1500 lines down to 70:
      #include <GUIConstants.au3> Global $g_sPathToPDF = ; path to some pdf file to show Opt("GUIOnEventMode", 1) ; default ist 0 ; 1 bedeutet, daß bei Klick direkt die darunterbeschriebene Funktion ausgeführt wird Global $g_hGUI_MAIN ; Haupt-GUI Global $g_hDummy_Main ; Dummy um Fokus in der Haupt-GUI unsichtbar zu setzen Global $g_hGUI_Pruefen ; GUI zum Prüfen aller PDF Global $g_hGUI_PDF ; GUI PDF-Ansicht der ausgewählten PDF Global $g_hPDF ; ActiveX control welches das PDF enthält Global $g_oAcrobatReader ; AcrobatReaderObjekt in dem die PDF gezeigt werden _GUI_Main() GUISetOnEvent ($GUI_EVENT_CLOSE, "_Exit_Main" , $g_hGUI_MAIN) While 1 Sleep(1) WEnd Exit Func _GUI_Main() ; GUI-MAIN $g_hGUI_MAIN = GUICreate("MAIN", 390, 390, 763, 372) GUISetFont(12) GUICtrlCreateButton("NEXT", 20, 20, 350, 55, $BS_DEFPUSHBUTTON) ; Default-Knopf GUICtrlSetOnEvent(-1, "_GUI_Pruefen") GUISetState(@SW_SHOW, $g_hGUI_MAIN) ; GUI anzeigen EndFunc Func _GUI_Pruefen() ; GUI zum Prüfen der PDF GUISetState(@SW_HIDE, $g_hGUI_MAIN) ; MAIN-GUI ausblenden Opt("GUIOnEventMode", 0) ; wieder auf Default gesetzt $g_hGUI_Pruefen = GUICreate("RIGHT", 490,950, 1057, 91, -1, $WS_EX_APPWINDOW, $g_hGUI_MAIN) _AcrobatShow($g_sPathToPDF, "", 367, 91, 674, 950, $g_hGUI_Pruefen) ; PDF-GUI erstellen GUISetState(@SW_SHOW, $g_hGUI_Pruefen) ; GUI-Prüfen anzeigen Local $msg While 1 $msg = GuiGetMsg() ; Aktion mit der GUI registrieren Switch $msg ; je nach Aktion mit der GUI Case $GUI_EVENT_CLOSE ; X gedrückt $g_oAcrobatReader = "" ; zerstöre das Objekt AcrobatReader GUIDelete($g_hGUI_PDF) ; lösche die GUI-PDF GUIDelete($g_hGUI_Pruefen) ; lösche die GUI-Prüfen Opt("GUIOnEventMode", 1) ; Default 0 GUISetState(@SW_SHOW, $g_hGUI_MAIN) ; MAIN-GUI wieder zeigen Return EndSwitch WEnd EndFunc Func _Exit_Main() ; ausführen, wenn die MAIN-GUI schließt ConsoleWrite("EXIT" & @CRLF) Exit EndFunc Func _AcrobatShow($sFile, $sTitle = "PDF ", $iLeft = 50, $iTop = 0, $iWidth = 1000, $iHeight = 700, $hWnd = "") ; GUI-PDF erstellen If FileExists($sFile) Then ; wenn das PDF existiert $g_oAcrobatReader = ObjCreate("AcroPDF.PDF.1") $g_oAcrobatReader.src = $sFile ; Quelle ist das File $g_oAcrobatReader.SetLayoutMode("SinglePage") ; default "SinglePage" $g_oAcrobatReader.SetPageMode("none") ; default "none" $g_oAcrobatReader.SetShowToolbar(0) ; Tool-Bar nicht zeigen 0 $g_oAcrobatReader.SetShowScrollbars(0) ; Scroll-Balken nicht zeigen 0 $g_oAcrobatReader.SetView("fit") ; "fit" falls wer eigene Einstellungen im Reader gespeichert hat $g_hGUI_PDF = GUICreate($sTitle, $iWidth, $iHeight, $iLeft, $iTop, -1, -1, $hWnd) ; GUI als Child zu GUI-PRUEFEN erstellen - es soll nicht aktiviert werden $g_hPDF = GUICtrlCreateObj($g_oAcrobatReader, 0, 0, $iWidth, $iHeight) ; Objekt für das PDF erstellen GUICtrlSetStyle($g_hPDF, $WS_VISIBLE) ; PDF anzeigen GUISetState(@SW_SHOW, $g_hGUI_PDF) ; GUI-PDF anzeigen Else MsgBox(0, 'ERROR', "No PDF found.") EndIf EndFunc Do following steps to prove:
      - start app
      - click "next" on main gui
      - wait minimum 5 seconds (until the arrows left and right on "gui left" disappear)
      - close gui left or right
      - close main gui
      - look on console written "EXIT" the last code line before exit
      - now windows error message above appears
      The funny thing is if I don't wait the 5 seconds (before the half transparent arrows disappear) closing the gui then I will get no win error message.
      If I comment _AcrobatShow() out then the error never appears. So it seemed to be an acrobat reader issue. Every week at work there are a lot of updates, but there is no chance to know which one. But since one update this error happens.
      Any solutions? Regards, Conrad
    • genius257
      By genius257
      I've made a library, based on AutoItObject UDF with the goal of implementing getter and setter functionality and make it possible to define new object properties in as few steps as possible.
      Thank you to @trancexx for getting me on the right track, and all users in Hooking into the IDispatch interface for the code to get me going.
      If I've forgotten to add credit, please let me know
      Example:
      #include "AutoItObject_Internal.au3" $myCar = IDispatch() $myCar.make = 'Ford' $myCar.model = 'Mustang' $myCar.year = 1969 $myCar.__defineGetter('DisplayCar', DisplayCar) Func DisplayCar($oThis) Return 'A Beautiful ' & $oThis.parent.year & ' ' & $oThis.parent.make & ' ' & $oThis.parent.model EndFunc MsgBox(0, "", $myCar.DisplayCar) More examples: https://github.com/genius257/AutoIt-projects/tree/master/AutoItObject Internal/Examples
      Version: 1.0.3
      AutoItObject_Internal.au3
      Documentation:
       

      Edit2 (19th March 2017):
      First of all, sorry about the lack of updates on this project. I always start too many projects and end up ignoring old projects, if I run into problems ^^'.
      So I've started moving my AutoIt scripts to GitHub. I will still post the most recent script version here.
×