Suche Elegante Lösung zur Vermeidung Globaler Variablen.

  • Hallo zusammen,

    ich suche nach einer Lösung um auf Globale Variablen zu verzichten. Folgender Hintergrund:

    In unsere Firma entwickeln wir viele Automatisierung die zum größten Teil auf eine Externe Anwendung zugreifen und bestimmte Aufgaben erledigen. Nun haben wir das Problem, dass alle 1-3 Monate die externe Anwendung aktualisiert wird und somit sich einige Control Instanzen, ID's, Namen usw ändern. Dadurch haben wir einen enormen Aufwand die, für das Programm erstellte UDF, mit den richtigen Daten zuspeisen, jedes einzelne Script neu Kompilieren und an alle Nutzer verteilen.

    Aus diesem Grund habe ich nun unsere UDF so angepasst, dass alle Daten aus mehreren INI Dateien gezogen werden und wir lediglich die Daten in den INI Dateien anpassen müssen. Dadurch ersparen wir uns das neu kompilieren und verteilen der Scripte.

    Nun zum eigentlichen Problem.

    Die INI ist wie folge aufgebaut:

    Spoiler anzeigen

    Mit dem folgenden Code erstelle ich nun die Globalen Variablen:

    Spoiler anzeigen
    [autoit]


    ;----------------------------------------------------------------------------------------------/
    ; Beschreibung: = Liest die INI's in ein Array und erstellt Globale Variablen
    ; Parameter: = ini Pfad (wird gemäß der Hash Version ermittelt)
    ; @return: = Globale Variablen
    ; @error: = (-)
    ;----------------------------------------------------------------------------------------------/
    func _get_ini($pf_INI)

    ;----------------------------------------------------------------------------------------------/
    ; Array
    ; 1 - Deminsonal
    ; [Dateiname]
    ;----------------------------------------------------------------------------------------------/
    Local Static $a_IniFiles[] = _
    [ _
    '\individual.ini', _
    '\ticket.ini', _
    '\Suchmasken.ini' _
    ]

    [/autoit] [autoit][/autoit] [autoit]

    ;----------------------------------------------------------------------------------------------/
    ; Lese INI Instance in Variablen ein.
    ; - Sectionname = Globale $variable
    ; - Sectionkey = String (Instance)
    ;----------------------------------------------------------------------------------------------/
    for $i = 0 to Ubound($a_IniFiles) -1
    $a_INI = IniReadSection($pf_INI & $a_IniFiles[$i], 'Instance')

    for $ii = 1 to Ubound($a_INI) -1
    Assign($a_INI[$ii][0], $a_INI[$ii][1], 2)
    next
    next
    endfunc ;<==/get_ini

    [/autoit]

    Warum ich bei Assign die Variablen Global setze hat den Grund, dass man überall im Script auf diese Variablen zurückgreift. Ich könnte natürlich die Instanzen in einem Array lassen und dieses jeder Funktion mit geben und über Array Index die Instanzen setzen, jedoch unterstützt AutoIt kein Assoziative Arrays sodass man beim Lesen des Scripts absolut den Überblick verliert und ein kleines Buch mit den Inhalt der Array neben sich liegen haben muss :)

    Ich hoffe einer von euch kann mir ein Denkanstoß verpassen :thumbup:

    • Offizieller Beitrag

    Wie wäre es so:

    [autoit]


    ; Inhalte aus INI - das kannst du natürlich als Array einlesen und dann in einer Schleife abarbeiten

    [/autoit][autoit][/autoit][autoit]

    _MyVars('saUDF_Information_Anrede', '[CLASS:Edit;INSTANCE:8]', 'set')
    _MyVars('saUDF_Information_Name', '[CLASS:Edit;INSTANCE:9]', 'set')
    _MyVars('saUDF_Information_Vorname', '[CLASS:Edit;INSTANCE:10]', 'set')

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite(_MyVars('saUDF_Information_Name') & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    Func _MyVars($_strVarName, $_value='', $_action='get')
    Local Static $oDict = ObjCreate('Scripting.Dictionary')
    Switch $_action
    Case 'get'
    If $oDict.Exists($_strVarName) Then
    Return $oDict.Item($_strVarName)
    Else
    Return SetError(1,0,'')
    EndIf
    Case 'set'
    If Not $oDict.Exists($_strVarName) Then
    $oDict.Add($_strVarName, $_value)
    Else
    $oDict.Item($_strVarName) = $_value
    EndIf
    EndSwitch
    EndFunc

    [/autoit]

    Edit: Ich hatte vergessen, dass Werte auch zur Laufzeit geändert werden können - jetzt korrigiert.

  • Perfekt das ist die Lösung, nach der ich gesucht habe.

    Meine Lösung:

    Spoiler anzeigen
    [autoit]


    _get_ini($pf_ini)
    $salUdf = _getSet_Salcus_Vars

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, 0, $salUdf('Information_Anrede'))
    MsgBox(0, 0, $salUdf('Information_Vorname'))

    [/autoit] [autoit][/autoit] [autoit]

    ;----------------------------------------------------------------------------------------------/
    ; Beschreibung: = Liest die INI's in ein Array und erstellt Globale Variablen
    ; Parameter: = ini Pfad (wird gemäß der Hash Version ermittelt)
    ; @return: = Globale Variablen
    ; @error: = (-)
    ;----------------------------------------------------------------------------------------------/
    func _get_ini($pf_INI)

    ;----------------------------------------------------------------------------------------------/
    ; Array
    ; 1 - Deminsonal
    ; [Dateiname]
    ;----------------------------------------------------------------------------------------------/
    Local Static $a_IniFiles[] = _
    [ _
    '\individual.ini', _
    '\ticket.ini', _
    '\Suchmasken.ini' _
    ]

    [/autoit] [autoit][/autoit] [autoit]

    ;----------------------------------------------------------------------------------------------/
    ; Lese INI Instance in Variablen ein.
    ; - Sectionname = Globale $variable
    ; - Sectionkey = String (Instance)
    ;----------------------------------------------------------------------------------------------/
    for $i = 0 to Ubound($a_IniFiles) -1
    $a_INI = IniReadSection($pf_INI & $a_IniFiles[$i], 'Instance')

    for $ii = 1 to Ubound($a_INI) -1
    _getSet_Salcus_Vars($a_INI[$ii][0],$a_INI[$ii][1],'set')
    next
    next
    endfunc ;<==/get_ini

    [/autoit] [autoit][/autoit] [autoit]

    ;----------------------------------------------------------------------------------------------/
    ; Beschreibung: = Funktions Beschreibung
    ; Parameter: = $_strVarName = Name der Sektion
    ; = $_value = Wert der Sektion = Default = ''
    ; = $_action = Aktion die durchgeführt werden soll = Default = 'get'
    ; @return: = key Wert
    ; @error: = ()
    ;----------------------------------------------------------------------------------------------/
    func _getSet_Salcus_Vars($_strVarName, $_value='', $_action='get')

    Local Static $oDict = ObjCreate('Scripting.Dictionary')

    [/autoit] [autoit][/autoit] [autoit]

    Switch $_action
    Case 'get'
    If $oDict.Exists($_strVarName) Then
    Return $oDict.Item($_strVarName)
    Else
    Return SetError(1,0,'')
    EndIf
    Case 'set'
    If Not $oDict.Exists($_strVarName) Then
    $oDict.Add($_strVarName, $_value)
    Else
    $oDict.Item($_strVarName) = $_value
    EndIf
    EndSwitch
    endfunc ;<==/getSet_Salcus_Vars

    [/autoit]

    Vielen Vielen Dank :rock: