Datenübernahme von MSSQL System nach MSAccess

    • [ offen ]

      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:
      Positionserfassung.jpg



      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)
      sag nicht lol... entweder lach richtig oder halt die Klappe. :rofl:

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „msdotz“ () aus folgendem Grund: Bild ist nicht da

      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?
      UDFs:
      Active Directory (2014-07-21 - Version 1.4.1.1) - Download - Support - Example Scripts - Wiki
      OutlookEX (2014-07-27 - Version 1.0.0.0) - Download - Support - Example Scripts - Wiki
      ExcelChart (2013-01-21 - Version 0.3.1.1) - Download
      Excel - Example Scripts - Wiki
      Word - Wiki
      Tutorials:
      ADO - Wiki
      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
      sag nicht lol... entweder lach richtig oder halt die Klappe. :rofl:

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „msdotz“ ()

      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).
      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.
      UDFs:
      Active Directory (2014-07-21 - Version 1.4.1.1) - Download - Support - Example Scripts - Wiki
      OutlookEX (2014-07-27 - Version 1.0.0.0) - Download - Support - Example Scripts - Wiki
      ExcelChart (2013-01-21 - Version 0.3.1.1) - Download
      Excel - Example Scripts - Wiki
      Word - Wiki
      Tutorials:
      ADO - Wiki
    autoit.de Webutation