Re: Thread erstellt und dennoch ungültiger Speicherzugriff
Verfasst: 12.07.2016 13:45
Okay dann hier mal der Code, bitte mir nicht gleich jeden Fehler gleich um die Ohren hauen
Also ich erkläre mal kurz den Programmablauf, dann wird der Code evtl. verständlicher.
1. Das Programm wird gestartet
2. Der User gibt den Quell Pfad und den Ziel Pfad an, außerdem noch die Spalte der Dateien in welcher die erforderlichen Daten sind.
3. Es wird damit begonnen die 1.Datei einzulesen, aus der Spalte die der User angegeben hat werden die Daten gefiltert und in einer Variable (sendungsnummern$) gespeichert (diese Daten werden benötigt für die SQL-Abfrage)
4. Nachdem die Datei komplett gelesen wurde und die benötigten Dateien in einer Variable gespeichert sind wird die Verbindung zur Datenbank aufgebaut.
5. Übergeben wird das Select mit der Variable die die Daten aus der gelesenen Datei enthält.
(sql_abfrage$="select blablabla From blablabla Where substring(d.paketlabel from 1 for 11) in ("+sendungsnummern$+")")
6. Wurde die Datenbankabfrage erfolgreich beendet werden die Daten nun in eine Datei geschrieben
7. Jetzt wird die nächste Datei eingelesen...
Und hier der Code, ich hoffe ihr versteht ihn ein wenig. Bestimmt nicht gut programmiert aber er funktioniert bis auf das mit dem Thread
.

Also ich erkläre mal kurz den Programmablauf, dann wird der Code evtl. verständlicher.
1. Das Programm wird gestartet
2. Der User gibt den Quell Pfad und den Ziel Pfad an, außerdem noch die Spalte der Dateien in welcher die erforderlichen Daten sind.
3. Es wird damit begonnen die 1.Datei einzulesen, aus der Spalte die der User angegeben hat werden die Daten gefiltert und in einer Variable (sendungsnummern$) gespeichert (diese Daten werden benötigt für die SQL-Abfrage)
4. Nachdem die Datei komplett gelesen wurde und die benötigten Dateien in einer Variable gespeichert sind wird die Verbindung zur Datenbank aufgebaut.
5. Übergeben wird das Select mit der Variable die die Daten aus der gelesenen Datei enthält.
(sql_abfrage$="select blablabla From blablabla Where substring(d.paketlabel from 1 for 11) in ("+sendungsnummern$+")")
6. Wurde die Datenbankabfrage erfolgreich beendet werden die Daten nun in eine Datei geschrieben
7. Jetzt wird die nächste Datei eingelesen...
Und hier der Code, ich hoffe ihr versteht ihn ein wenig. Bestimmt nicht gut programmiert aber er funktioniert bis auf das mit dem Thread

Code: Alles auswählen
EnableExplicit
UsePostgreSQLDatabase()
UseODBCDatabase()
UsePNGImageDecoder()
Structure ThreadData
thread_sql_abfrage.s
thread_dateipfad.s
thread_dateiname.s
thread_ziel_verzeichnis.s
EndStructure
Declare main()
Declare verzeichnis_scannen(quell_verzeichnis$, dateiendung$, ziel_verzeichnis$)
Declare dateien_erzeugen(dateipfad$)
Declare sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
Declare sql_abfrage_ausfuehren(sql_abfrage$, dateipfad$, dateiname$, ziel_verzeichnis$)
Declare Thread(*tData.ThreadData)
Global anzahl_nbgut=0
Global nbgut_kennzeichen_spalte
Global nbgut_kennzeichen
Global sendungsnummer_spalte
Global Hauptfenster=0
Global button_info = CatchImage(#PB_Any, ?INFO)
ResizeImage(button_info, 40, 40)
DataSection
INFO:
IncludeBinary "info.png"
EndDataSection
main()
Procedure main()
Protected Button_Quell_Pfad, String_Quell_Pfad, Button_Create_Files, Button_Abbrechen, Text_NB_Gut_Kz_Spalte, String_NB_Gut_Kz_Spalte, Text_NB_Gut_Kz, String_NB_Gut_Kz, Text_Sendungsnr_Spalte, String_Sendungsnr_Spalte, Button_Ziel_Pfad, String_Ziel_Pfad
Protected Frame_1, Option_Ja, Option_Nein, ButtonImage_Info
Protected Event
Protected quell_verzeichnis$, ziel_verzeichnis$, verzeichnishandle, verzeichnisname$
Protected dateiendung$ =".csv"
Protected s.l
Protected eingaben_ok=1
If OpenWindow(Hauptfenster, 0, 0, 500, 230, "GLS NB-Gut Filtern", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
Button_Quell_Pfad = ButtonGadget(#PB_Any, 10, 10, 110, 22, "Quelle auswählen")
String_Quell_Pfad = StringGadget(#PB_Any, 130, 11, 360, 20, "")
Text_NB_Gut_Kz= TextGadget(#PB_Any, 135, 58, 150, 20, "NB-Gut Kennzeichen:", #PB_Text_Right)
String_NB_Gut_Kz= StringGadget(#PB_Any, 290, 55, 20, 20, "2")
SetGadgetAttribute(String_NB_Gut_Kz, #PB_String_MaximumLength, 2)
Text_NB_Gut_Kz_Spalte= TextGadget(#PB_Any, 135, 88, 150, 20, "NB-Gut Kennzeichen in Spalte:", #PB_Text_Right)
String_NB_Gut_Kz_Spalte= StringGadget(#PB_Any, 290, 85, 20, 20, "8", #PB_String_Numeric)
SetGadgetAttribute(String_NB_Gut_Kz_Spalte, #PB_String_MaximumLength, 2)
Text_Sendungsnr_Spalte= TextGadget(#PB_Any, 135, 118, 150, 20, "Sendungsnummer in Spalte:", #PB_Text_Right)
String_Sendungsnr_Spalte= StringGadget(#PB_Any, 290, 115, 20, 20, "4", #PB_String_Numeric)
SetGadgetAttribute(String_Sendungsnr_Spalte, #PB_String_MaximumLength, 2)
Frame_1 = FrameGadget(#PB_Any, 340, 65, 150, 55, "Ordner Rekursiv scannen")
Option_Ja = OptionGadget(#PB_Any, 375, 85, 30, 25, "ja")
Option_Nein = OptionGadget(#PB_Any, 430, 85, 40, 25, "nein")
Button_Ziel_Pfad = ButtonGadget(#PB_Any, 10, 160, 110, 22, "Ziel auswählen")
String_Ziel_Pfad = StringGadget(#PB_Any, 130, 161, 360, 20, "")
Button_Abbrechen = ButtonGadget(#PB_Any, 390, 200, 100, 22, "Abbrechen")
Button_Create_Files = ButtonGadget(#PB_Any, 280, 200, 100, 22, "Dateien erstellen")
ButtonImage_Info = ButtonImageGadget(#PB_Any, 20, 70, 50, 50, ImageID(button_info))
s.l=GetWindowLong_(GadgetID(ButtonImage_Info), #GWL_STYLE)
SetWindowLong_(GadgetID(ButtonImage_Info.i), #GWL_STYLE, #BS_FLAT | #BS_OWNERDRAW | s)
SetGadgetState(Option_Ja, 1)
EndIf
Repeat
Event = WaitWindowEvent()
If Event=#PB_Event_Gadget
Select EventGadget()
Case Button_Quell_Pfad
quell_verzeichnis$=PathRequester("Bitte wählen Sie einen Pfad aus", "")
SetGadgetText(String_Quell_Pfad, quell_verzeichnis$)
Case Button_Ziel_Pfad
ziel_verzeichnis$=PathRequester("Bitte wählen Sie einen Pfad aus", "")
SetGadgetText(String_Ziel_Pfad, ziel_verzeichnis$)
Case Button_Create_Files
ziel_verzeichnis$=GetGadgetText(String_Ziel_Pfad)
quell_verzeichnis$=GetGadgetText(String_Quell_Pfad)
If GetGadgetText(String_Quell_Pfad) =""
MessageRequester("Info", "Bitte Quell Ordner auswählen")
eingaben_ok=0
EndIf
If GetGadgetText(String_NB_Gut_Kz) =""
MessageRequester("Info", "Bitte NB-Gut Kennzeichen angeben")
eingaben_ok=0
EndIf
If GetGadgetText(String_NB_Gut_Kz_Spalte) =""
MessageRequester("Info", "Bitte Spalte für NB-Gut Kennzeichen angeben")
eingaben_ok=0
EndIf
If GetGadgetText(String_Sendungsnr_Spalte) =""
MessageRequester("Info", "Bitte Spalte für Sendungsnummer angeben")
eingaben_ok=0
EndIf
If GetGadgetText(String_Ziel_Pfad) =""
MessageRequester("Info", "Bitte Ziel Ordner auswählen")
eingaben_ok=0
EndIf
If quell_verzeichnis$ <> "" And ziel_verzeichnis$ <> "" And dateiendung$ <> "" And eingaben_ok=1
nbgut_kennzeichen_spalte=Val(GetGadgetText(String_NB_Gut_Kz_Spalte))
nbgut_kennzeichen=Val(GetGadgetText(String_NB_Gut_Kz))
sendungsnummer_spalte=Val(GetGadgetText(String_Sendungsnr_Spalte))
Debug "NB_Gut_Kennzeichen: "+nbgut_kennzeichen
Debug "NB_Gut_Kennzeichen_Spalte: "+nbgut_kennzeichen_spalte
Debug "Sendungsnummer Spalte: "+sendungsnummer_spalte
quell_verzeichnis$=GetGadgetText(String_Quell_Pfad)
Debug quell_verzeichnis$
;DisableWindow(0, #True)
verzeichnishandle = ExamineDirectory(#PB_Any, quell_verzeichnis$, dateiendung$)
verzeichnis_scannen(quell_verzeichnis$, dateiendung$, ziel_verzeichnis$)
EndIf
Case ButtonImage_Info
MessageRequester("Info", "Das Programm filtert alle Sendungsnummern und zugehörige Artikelnummern heraus, welche von .....usw.")
Case Button_Abbrechen
SetGadgetText(String_Quell_Pfad, "")
SetGadgetText(String_Ziel_Pfad, "")
SetGadgetText(String_NB_Gut_Kz, "")
SetGadgetText(String_NB_Gut_Kz_Spalte, "")
SetGadgetText(String_Sendungsnr_Spalte, "")
SetGadgetText(String_Ziel_Pfad, "")
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
EndProcedure
Procedure.i verzeichnis_scannen(quell_verzeichnis$, dateiendung$, ziel_verzeichnis$)
Debug "Verzeichnis: "+quell_verzeichnis$
Debug "Dateiendung: "+dateiendung$
Protected verzeichnishandle
Protected verzeichnisname$
Protected modifydatum$
Protected dateiname$
Protected dateipfad$
Protected scan_rekursiv=1
Protected endung$
If Right(quell_verzeichnis$, 1) <> "\" And Right(quell_verzeichnis$, 1) <> "/"
quell_verzeichnis$ = quell_verzeichnis$+"\"
EndIf
verzeichnishandle = ExamineDirectory(#PB_Any, quell_verzeichnis$, "*.*")
If scan_rekursiv =1
Debug "Rekursiv Scannen!"
If verzeichnishandle <> 0
While NextDirectoryEntry(verzeichnishandle)
verzeichnisname$ = DirectoryEntryName(verzeichnishandle)
If DirectoryEntryType(verzeichnishandle) = #PB_DirectoryEntry_Directory
If verzeichnisname$ <> "." And verzeichnisname$ <> ".."
verzeichnis_scannen (quell_verzeichnis$+verzeichnisname$, dateiendung$, ziel_verzeichnis$)
EndIf
EndIf
If DirectoryEntryType(verzeichnishandle) = #PB_DirectoryEntry_File
dateipfad$=quell_verzeichnis$+DirectoryEntryName(verzeichnishandle)
dateiname$=DirectoryEntryName(verzeichnishandle)
Debug dateipfad$
Debug dateiname$
If GetExtensionPart(dateipfad$) = "csv"
sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
anzahl_nbgut=0
EndIf
EndIf
Wend
FinishDirectory(verzeichnishandle)
EndIf
ElseIf scan_rekursiv = 0
Debug "Nicht rekursiv scannen!"
If verzeichnishandle <> 0
While NextDirectoryEntry(verzeichnishandle)
verzeichnisname$ = DirectoryEntryName(verzeichnishandle)
If DirectoryEntryType(verzeichnishandle) = #PB_DirectoryEntry_Directory
EndIf
If DirectoryEntryType(verzeichnishandle) = #PB_DirectoryEntry_File
EndIf
Wend
FinishDirectory(verzeichnishandle)
EndIf
EndIf
If verzeichnishandle = 0
MessageRequester("Info", "Fehler: Keine Dateien im Quell-Verzeichnis gefunden")
EndIf
EndProcedure
Procedure sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
Protected sql_abfrage$
Protected zeile$
Protected sendungsnummer$=""
Protected sendungsnummern$=""
Protected csv_file
Protected Thread
Protected i
Protected test
If ReadFile(0, dateipfad$) ; wenn die Datei geöffnet werden konnte, setzen wir fort...
While Eof(0) = 0 ; sich wiederholende Schleife bis das Ende der Datei ("end of file") erreicht ist
zeile$ = ReadString(0, #PB_Ascii) ; Zeile für Zeile im Debugger-Fenster anzeigen
If StringField(zeile$, nbgut_kennzeichen_spalte, ";") = Str(nbgut_kennzeichen)
sendungsnummer$= StringField(zeile$, sendungsnummer_spalte, ";")
anzahl_nbgut+1
If anzahl_nbgut=1
sendungsnummern$="'"+sendungsnummer$+"'"
Else
sendungsnummern$=sendungsnummern$+","+"'"+sendungsnummer$+"'"
EndIf
EndIf
Wend
Debug "Anzahl NB-Gut: "+anzahl_nbgut
Debug "Sendungsnummern: "+sendungsnummern$
If sendungsnummern$ <> ""
sql_abfrage$="select blablabla From blablabla Where substring(d.paketlabel from 1 for 11) in ("+sendungsnummern$+")"
Debug sql_abfrage$
;DisableWindow(Hauptfenster, #True)
Define *tData.ThreadData = AllocateStructure(ThreadData)
*tData\thread_sql_abfrage=sql_abfrage$
*tData\thread_dateipfad=dateipfad$
*tData\thread_dateiname=dateiname$
*tData\thread_ziel_verzeichnis=ziel_verzeichnis$
Thread = CreateThread(@Thread(), *tData)
;sql_abfrage_ausfuehren(sql_abfrage$, dateipfad$, dateiname$, ziel_verzeichnis$)
EndIf
CloseFile(0)
Else
MessageRequester("Information","Konnte Datei nicht öffnen!")
EndIf
EndProcedure
Procedure Thread(*tData.ThreadData)
sql_abfrage_ausfuehren(*tData\thread_sql_abfrage,*tData\thread_dateipfad, *tData\thread_dateiname, *tData\thread_ziel_verzeichnis)
FreeMemory(*tData)
EndProcedure
Procedure sql_abfrage_ausfuehren(sql_abfrage$, dateipfad$, dateiname$, ziel_verzeichnis$)
Protected export_datenbank$="host=x.x.x.x port=xxxx dbname=xxxxx" ;LIVE DATENBANK!!!
Protected anzahl_spalten=0
Protected speicherpfad$
Protected i
Protected spalten_typ$
Protected anzahl_datensaetze
Protected datensatz$
Protected csv_file
Protected abfrage$
Protected thread
If Right(ziel_verzeichnis$, 1) <> "\" And Right(ziel_verzeichnis$, 1) <> "/"
ziel_verzeichnis$ = ziel_verzeichnis$+"\"
EndIf
speicherpfad$=ziel_verzeichnis$+dateiname$
csv_file = CreateFile(#PB_Any, Mid(speicherpfad$, 1, Len(speicherpfad$)-4)+"_NB_Gut.csv")
If csv_file
If OpenDatabase(1, export_datenbank$, "xxxx", "xxxx", #PB_Database_PostgreSQL)
Debug "Verbindung zur Datenbank erolgreich! "+sql_abfrage$
abfrage$=sql_abfrage$
If DatabaseQuery(1, abfrage$)
anzahl_spalten = DatabaseColumns(1) ; Gibt die Anzahl an Spalten von der letzten Datenbank-Abfrage zurück.
Debug "Anzahl Spalten: "+ anzahl_spalten
For i = 0 To anzahl_spalten-1
If i=0
WriteString(csv_file, DatabaseColumnName(1, i),#PB_Ascii)
spalten_typ$=spalten_typ$+DatabaseColumnType(1, i)
EndIf
If i > 0
If i = anzahl_spalten-1
WriteStringN(csv_file, ";"+DatabaseColumnName(1, i),#PB_Ascii)
spalten_typ$=spalten_typ$+";"+DatabaseColumnType(1, i)
Else
WriteString(csv_file, ";"+DatabaseColumnName(1, i),#PB_Ascii)
spalten_typ$=spalten_typ$+";"+DatabaseColumnType(1, i)
EndIf
EndIf
Next
;FinishDatabaseQuery(1)
Debug spalten_typ$
;If DatabaseQuery(1, sql_abfrage$)
While NextDatabaseRow(1)
anzahl_datensaetze=anzahl_datensaetze+1
Debug "---------------------------"
For i = 1 To anzahl_spalten
Debug "Anzahl Spalten: "+anzahl_spalten
If i=1
Debug "i=1"
Select StringField(spalten_typ$, i, ";")
Case "1"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
Case "2"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
Case "3"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
Case "4"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
Case "5"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
Case "6"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
EndSelect
EndIf
If i > 1
If i = anzahl_spalten
Debug "i=1 und gleich anzahl spalten"
Select StringField(spalten_typ$, i, ";")
Case "1"
;Debug GetDatabaseString(1, i-1)
datensatz$=GetDatabaseString(1, i-1)
If FindString(datensatz$, ".")
datensatz$=ReplaceString(datensatz$, ".", ",")
EndIf
WriteStringN(csv_file, ";"+datensatz$,#PB_Ascii)
Debug "Datensatz$: "+datensatz$
Case "2"
Debug GetDatabaseString(1, i-1)
WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
Case "3"
Debug GetDatabaseString(1, i-1)
WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
Case "4"
Debug GetDatabaseString(1, i-1)
WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
Case "5"
Debug GetDatabaseString(1, i-1)
WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
Case "6"
Debug GetDatabaseString(1, i-1)
WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
EndSelect
Else
Debug "i ist größer 1 aber kleiner anzahl spalten"
Select StringField(spalten_typ$, i, ";")
Case "1"
;Debug GetDatabaseString(1, i-1)
datensatz$=GetDatabaseString(1, i-1)
If FindString(datensatz$, ".")
datensatz$=ReplaceString(datensatz$, ".", ",")
EndIf
WriteString(csv_file, ";"+datensatz$,#PB_Ascii)
Debug "Datensatz$: "+datensatz$
Case "2"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
Case "3"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
Case "4"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
Case "5"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
Case "6"
Debug GetDatabaseString(1, i-1)
WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
EndSelect
EndIf
EndIf
Next
Wend
;Else
;MessageRequester("Fehler", "Kann die folgende Abfrage nicht ausführen: "+DatabaseError())
;EndIf
FinishDatabaseQuery(1)
CloseDatabase(1)
CloseFile(csv_file)
;MessageRequester("CSV-Datei wurde erzeugt", "Erzeugte Datensätze: "+anzahl_datensaetze)
Else
MessageRequester("Fehler", "Kann die folgende Abfrage nicht ausführen: "+DatabaseError())
EndIf
Else
Debug "Connection failed: "+DatabaseError()
MessageRequester("Connected to PostgreSQL","Failed!")
End
EndIf
Else
MessageRequester("Information","Konnte Datei nicht erstellen!")
EndIf
Debug "Dateiname: "+dateiname$
Debug "Zielverzeichnis:"+ziel_verzeichnis$
Debug "Speicherpfad: "+speicherpfad$
EndProcedure