Datenübernahme von MSSQL System nach MSAccess

  • Hallo zusammen,

    ich bin an meinem ersten Projekt mit Autoit und habe schon einige Probleme aus der Welt geschafft. Ich hoffe ich bin hier in der richtigen Abteilung.

    Hintergrund:

    Ich muss Daten von einem Warenwirtschaftssystem (MSSQL-Datenhaltung) in ein neues mit MS-Access-Datenhaltung übernehmen.
    Die einfachen Dinge des Lebens (Übernahme von Kunden, Lieferanten und Artikeln im CSV-Format) werden vom neuen System bereitgestellt.
    Das hat schon alles funktioniert.

    Aufgabe:
    Aber : Man(n) braucht natürlich auch die alten Daten ( Angebote, Aufträge, Bestellungen, Lieferscheine, Rechnungen und Projekte) aus 2011 - 2006.
    Ich konnte bisher alle Probleme selbst lösen. Aber jetzt hänge ich fest.

    Problem:
    Bei der Übergabe der einzelnen Positionen zu einem Vorgang kommt es immer wieder zum "Inputfeld-kenne-ich-nicht-Effekt"

    Der Bilschirm sieht so aus:
    autoit.de/wcf/attachment/13609/


    Die Funktion sieht so aus:

    Spoiler anzeigen

    Func BELEGPOSITIONEN_IMPORT($strBelegTyp, $STRBELEGNUMMER, $STRKUNDE, $STRPROJEKTNAME)

    Local $rsBelegP
    Local $strSQL = ""
    Local $Kennung = 0
    Local $Menge = 0
    Local $strME = "Stück"
    Local $strArtikelnummer = ""
    Local $strArtikelBezeichnung = ""
    Local $strArtikelZusatz = ""
    Local $ArtikelEPreis = 0
    Local $strArtikelLangText = ""
    Local $LangTextLaenge = 0
    Local $strString = ""
    Local $strControlID = ""
    Local $strClass = ""
    Local $Posnummer = 0
    Local $Editnummer = 0
    Local $c = 0
    Local $HWnd = ""
    Local $HWndEdit = ""
    Local $strTitle = ""

    $strSQL = "SELECT * FROM BELEGP WHERE BELEGP.Belegtyp = '" & $strBelegTyp & "' AND BELEGP.Belegnummer='" & $STRBELEGNUMMER & "'"
    $strSQL = $strSQL & " AND Zeilentyp in ('A') AND BELEGP.Artikelnummer <> '' AND Menge > 0 ORDER BY BELEGP.Posnummer;"

    ADO_OPEN_RECORDSET($ADOCONN, $rsBelegP, $strSQL) ; Gibt Recordset zurück

    ; Weiter mit der Positionsverarbeitung
    BlockInput(1)

    Sleep(1000)
    MsgBox(262144, "DEBUG Belegkopf", "Wurde jetzt geschlossen ...", 2)
    Sleep(1000)
    MsgBox(262144, "DEBUG Ordner Fenster", "Jetzt muss Positionsverarbeitung geöffnet werden ...", 2)
    MouseMove( 540, 500 ) ; Maus auf Positons-Button
    MouseClick("Left", 540,500, 1 )

    Sleep(1000)

    ;Sleep(300)
    ;Send("{ALTDOWN}p{ALTUP}") ; Positionsverarbeitung öffnen DAS FUNKTIONIERT SO GUT WIE NIE, DESHALB OBEN DER MAUSKLICK.
    Sleep(500)
    MsgBox(262144,"DEBUG BelegP","Eingabe Positionsart/ Anzahl Positionen " & $rsBelegP.Recordcount, 2)

    $strTitle = $STRKUNDE & " / "
    $HWnd = WinActivate($strTitle,$STRPROJEKTNAME)

    if IsHWnd($HWnd) Then

    While Not $rsBelegP.EOF

    $Kennung = $rsBelegP.Fields("Kennung" ).Value ; Wird für den Langtext-Schlüssel gebraucht
    $Menge = $rsBelegP.Fields("Menge" ).Value

    $strME = "Stück"
    $strArtikelnummer = $rsBelegP.Fields("Artikelnummer" ).Value
    $strArtikelBezeichnung = $rsBelegP.Fields("Bezeichnung" ).Value
    $strArtikelZusatz = $rsBelegP.Fields("Zusatz" ).Value
    $ArtikelEPreis = $rsBelegP.Fields("Einzelpreis" ).Value

    ; Langtext lesen , falls vorhanden
    $strSQL = "BPKennung=" & $Kennung
    $strBelegTyp = "BP"
    $strString = ""
    $strArtikelLangText = ""
    $strArtikelLangText = ADO_ReadDBField_Text($ADOCONN, $strSQL, $strBelegTyp, $strString)

    $LangTextLaenge = StringLen($strArtikelLangText)

    MsgBox(262144,"DEBUG BelegP","Position : " & $strArtikelnummer, 2)
    MsgBox(262144,"DEBUG BelegP","Rein in die Menge " & $Menge, 2)

    $Posnummer = $Posnummer + 1
    #cs


    -----------------------------------------------------------------------------------------------
    So hätte ich es gerne, aber so funktioniert es nicht
    -------------------------------------------------------------------------------------------


    $EditBelegnummer = 0
    $HWndEdit = ErmittleEditHandle($Posnummer, $EditBelegnummer)

    If IsHWnd($HWndEdit) Then
    ControlSetText($HWndEdit,"","",">") ; Positionsart
    EndIf

    $EditBelegnummer = 1
    $HWndEdit = ErmittleEditHandle($Posnummer, $EditBelegnummer)
    If IsHWnd($HWndEdit) Then
    ControlSetText($HWndEdit,"","","{TAB}") ; Positionnummernfeld
    EndIf

    $EditBelegnummer = 2
    $HWndEdit = ErmittleEditHandle($Posnummer, $EditBelegnummer)
    If IsHWnd($HWndEdit) Then
    ControlSetText($HWndEdit,"","","{DEL 10}" & $Menge) ; Menge
    EndIf
    Sleep(2000)

    $EditBelegnummer = 1001
    $HWndEdit = ErmittleEditHandle($Posnummer, $EditBelegnummer)
    If IsHWnd($HWndEdit) Then
    ControlSetText($HWndEdit,"","","Stück") ; Mengeneinheit
    EndIf

    $EditBelegnummer = 4
    $HWndEdit = ErmittleEditHandle($Posnummer, $EditBelegnummer)
    If IsHWnd($HWndEdit) Then
    ControlSetText($HWndEdit,"","",$strArtikelnummer & "{ENTER}") ; Arikelnummer
    EndIf
    #ce

    ; ------------------------------------------------------------------------------------------------------------
    ; Alternativer Ansatz, geht aber auch nicht.
    ;-------------------------------------------------------------------------------------------------------------
    ControlClick("[CLASS:Edit; INSTANCE:7]", "[ID:2]",1)
    MsgBox(262144,"DEBUG BelegP","Rein in die Menge " & $Menge, 2)

    ControlSend("[CLASS:Edit; INSTANCE:7]","",2,"{DEL 10}" & $Menge) ; Menge
    ControlSend("[CLASS:Edit; INSTANCE:8]","",1001,"Stück{TAB}") ; Mengeneinheit

    Send($strArtikelnummer & "{ENTER}") ; Arikelnummer

    Send("^a{DEL}") ; Automatische Texte aus Artikelstamm markieren und entfernen
    Sleep(1000)
    Send($strArtikelnummer & "{ENTER}") ; Artikelnummer und Bezeichnung in den Langtext eintragen
    Sleep(500)
    Send($strArtikelBezeichnung & " " & $strArtikelZusatz & "{ENTER}")
    Sleep(500)

    ; Langtext einfügen
    If $LangTextLaenge > 0 then
    Send(@CRLF & $strArtikelLangText)
    EndIf
    ; Texte Übergabe abschliessen mit TAB
    Send("{TAB}")

    ; Einzelpreis einfügen
    Send($ArtikelEPreis & "{TAB}")
    Sleep(500)

    $rsBelegP.MoveNext
    WEnd
    EndIf

    Send("{F2}") ; Endsummen eintragen
    Sleep(1000)

    Send("{F8}") ; Speichern und Schliessen
    Sleep(1000)
    $rsBelegP.Close
    BlockInput(0)
    Return True
    EndFunc ;==>BELEGPOSITIONEN_IMPORT

    Das Problem liegt darin, dass das erste Editfeld nicht gefunden wird (Edit7). Wo liegt da mein Fehler?
    Wenn ich jetzt hier noch die Ausgabe von Au3Info rein kopieren, ist meine schöne Formatierung zerhackt. Grübel!!
    Egal, hier ist die Ausgabe:

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

    >>>> Window <<<<
    Title:10036 / Angebot A06/000027 (VB-50037)
    Class:Afx:00400000:b:00010003:00000006:000C06C9
    Position:-8, -8
    Size:1382, 784
    Style:0x15CF0000
    ExStyle:0x00000100
    Handle:0x000206DA

    >>>> Control <<<<
    Class:Edit
    Instance:7
    ClassnameNN:Edit7
    Name:
    Advanced (Class):[CLASS:Edit; INSTANCE:7]
    ID:2
    Text:
    Position:178, 358
    Size:75, 24
    ControlClick Coords:43, 16
    Style:0x50000006
    ExStyle:0x00000000
    Handle:0x00010702

    >>>> Mouse <<<<
    Position:225, 399
    Cursor ID:0
    Color:0xFFFFFF

    >>>> StatusBar <<<<
    1:
    2:
    3:
    4:Summe:
    5:3.800,00 EUR

    >>>> ToolsBar <<<<

    >>>> Visible Text <<<<
    KOPF
    Angebot


    Datum

    Nummer

    17.07.2006

    A06/000027
    TEXT
    Betreff:

    TEXT
    Sehr geehrter Herr,

    TEXT
    wir danken für Ihre Anfrage und bieten wie folgt an:
    >
    SERV.M001
    Service oder Dienstleistung Hardware

    Service oder Dienstleistung an Hardware


    01.01
    1,00
    Std
    Std
    3.800,00
    3.800,00
    Weitere Funktionen
    100%
    100%


    >>>> Hidden Text <<<<
    ?
    Positionseingabe starten (F5)
    -------------------------------------------------------------------------------


    Ich hoffe jemand kann was damit anfangen und mir einen Tipp geben. Langsam bekomme ich Pickel im Gesicht.
    Danke vorab und L.G.

    MsDotz (Autoit- Greenhorn)

  • Du hast zwei Systeme die SQL verstehen. Wäre es da nicht sinnvoller, direkt auf die MS SQL Datenbank zuzugreifen, die notwendigen Datensätze auszulesen und in die MS Access DB zu schreiben?

    N.B. Warenwirtschaftssystem mit MS Access Datenhaltung? Was ist denn das für eine Verbesserung? Oder ist Access nur das Frontend?

  • Hallo Water,


    über die Sinnhaltigkeit einer Datenhaltung in Access in Verbindung mit einer WaWi müssen wir nicht diskutieren. Es ist nun mal so. Leider sind Teile der Daten in Binärfeldern abgelegt, deren Struktur wird nicht kommuniziert. DB 2 DB mittels SQL fällt also aus.
    Was ich brauche ist eine sichere Ermittlung der HWnds in der abgebildeten Positionszeile. Fakt ist, der Focus ist beim Öffnen des Fensters immer im ersten Feld mit ">" (= normale Artikelposition) .
    Leider funktioniert hier, aus Gründen, die ich noch nicht kenne , ein Füllen der Felder mit Send($var & "{TAB}") nicht zuverlässig. Auch Änderungen in den Opts bei SendDelay etc. macht das Ganze nicht sicherer.
    Daher wollte ich den Weg über die HWnds der Eingabefelder gehen. Da die Zeilen dynamisch erzeugt werden, ändern sich auch die Bezeichnungen der Editfelder. Also Edit6 wird in der zweiten Zeile zu Edit13 und in der dritten zu Edit 20.

    Gibt es eine Funktion, der ich den Namen eines Controls in einer Variblen übergeben kann und die mir bei Erfolg den HWnd zurückgibt?
    Und kann ich den HWnd eines Controls in jeder Funktion statt "[CLASS:xxxxxx; INSTANCE:y]" verwenden?
    Also : ControlClick($HWnd, "",$Controlname) ? Die Hilfe ist hier nicht besonders hilfreich.
    Zitat:
    "Control Handle (HWND)
    Using the ControlGetHandle function you can determine the Handle or HWND of a control. A handle is the unique identifier that Windows gives controls. The handle changes each time the control is created. This method of accessing controls is generally only designed for users who are familiar with working with handles."


    Das beliebte Notepad-Beispiel ist hier leider nur suboptimal zur Problemlösung.


    Bei ca. 2300 Belegen mit insgesamt ca. 8000 Positionen lohnt sich so ein Script schon.

    hoffe jemand hat eine Lösung. Ich probiere mal weiter. Wenns den zuverlässig klappt hört ihr den Aufschrei durch die gesamte Republik ;) .

    Schönes WE

    MsDotz

    Einmal editiert, zuletzt von msdotz (25. Juni 2011 um 09:21)

  • Zitat

    Gibt es eine Funktion, der ich den Namen eines Controls in einer Variblen übergeben kann und die mir bei Erfolg den HWnd zurückgibt?

    ControlGetHandle ist da schon die richtige Funktion. Die notwendige ControlID kannst Du auf viele verschiedene Arten angeben. Guckst Du hier (englisch) oder hier (deutsch). Was Du angibst, hängt davon ab, was eindeutig und verfügbar ist.
    Eine andere Möglichkeit wäre, eine Liste aller Controls erstellen zu lassen und dann die richtigen auszuwählen (hab derzeit aber keine Ahnung ob/wie das geht).

    Zitat

    Und kann ich den HWnd eines Controls in jeder Funktion statt "[CLASS:xxxxxx; INSTANCE:y]" verwenden?

    Ja. HWnd ist unique bis das Control neu erstellt wird d.h. das GUI neu generiert wird.