//FormHtml_1.prg 26.08.2023 18:40 //Sammlung der Funktionen fr die indiText/indiForm // sammelt alle Funktionen aus KSOX fr den Formulardruck per HTML und OpenOffice-Writer // fr alle anderen Bestatter AUSSER KSOX (fr KSOX bernimmt FormHtml_2 diese Aufgabe!) #include "Gra.ch" #include "Xbp.ch" #include "Appevent.ch" #include "Appedit.ch" #include "Appbrow.ch" #include "Font.ch" #include "Common.ch" #include "Dll.ch" #include "Dmlb.ch" #include "Common.ch" #include "fileio.ch" #include "directry.ch" //14.02.2026 18:22 mit HTML_Brief_2 abgeglichen: FUNCTION HTML_Brief_1( cFile, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez ) //18.10.2022 cZeileMM -> cZeileCM // cNotiz_Bez LOCAL nZei := 8, nAnf, CR := Chr(13), LF := Chr(10) LOCAL nHandle, cBuffer, nBytes, cText, cNeuTxt := "" LOCAL cDatv := cDatver LOCAL nFSize, nFHoehe, nFBreite LOCAL nZeileMM LOCAL cSZeit, nSZeit, cFZeit, nFZeit, nZ //30.12.2022 15:29 warten aufs PDF LOCAL dHeute, dFDatum, cVermerk //19.02.2024 15:48 nachtr„glich als LOCAL erkl„rt LOCAL aFormSeite //18.02.2026 10:11 //05.01.2024 15:33 der Link zum PDF-Programm ist in der Datei PdfProgLinks vvvvvvvvvv LOCAL cTextPP := IIf(FExists(cDatver+"PdfProgLinks.txt"),MemoRead(cDatver+"PdfProgLinks.txt"),"") LOCAL nMaxLines := MlCount(cTextPP, 90) LOCAL aPPLinks[nMaxLines], n PRIVATE cPPLinks := cTextPP DEFAULT cFormular TO "" DEFAULT cFont TO '"Times New Roman", serif' DEFAULT cFSize TO '18pt' DEFAULT cFormSeite TO '1cm 1cm 1cm 2cm' DEFAULT cZeileCM TO '0.14' //11.10.2022 14:58 Zeilenabstand //08.01.2024 10:45 in inditext_1() PRIVATE cBuero //11.10.2022 16:56 PRIVATE fr VariFunkErsatz_1 nFSize := Val(cFSize) nFHoehe := nFSize * 0.352778 nFBreite := nFSize * 0.2 // 0.2 ist ein gesch„tzter vorl„ufiger Wert nZeileMM := IIf(Val(cZeileCM)<0.2, nFHoehe * Val(cZeileCM)*10, Val(cZeileCM)*10) // DO WHILE At("\",cDatv) > 0 // cDatv := Stuff( cDatv, At("\",cDatv), 1, "/" ) // ENDDO IF !"HDBE"$Upper(cFormular) cFormular := Stuff(cFormular,At("\",cFormular),1,"/") cFormular := "file:///c:/bestatt/bleines/"+cFormular //cDatv + cFormular ENDIF // Zur Vermeidung von Kollision verschiedener Drucke vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // Test: ist bereits die Datei HTML_Brief.html auf diesem PC ge”ffnet? IF FExists("c:\hdbe\HTML_Brief.html") //22.12.2022 19:13 nHandle := FOpen( "c:\hdbe\HTML_Brief.html", FO_EXCLUSIVE ) IF nHandle = -1 //+ Die Datei ist bereits auf diesem PC ge”ffnet FClose(nHandle) msgbox("Es ist bereits ein HTML_Brief.html offen!"+CR+LF+"Bitte OfficeWriter schlieáen, dann nochmal versuchen!") RETURN .F. ELSE FClose(nHandle) ENDIF ENDIF //-------------------------------- // Test: ist bereits die Datei HTML_Brief.pdf auf diesem PC ge”ffnet? IF FExists("c:\hdbe\HTML_Brief.pdf") //22.12.2022 19:13 nHandle := FOpen( "c:\hdbe\HTML_Brief.pdf", FO_EXCLUSIVE ) IF nHandle = -1 //+ Die Datei ist bereits auf diesem PC ge”ffnet FClose(nHandle) msgbox("Es ist bereits ein HTML_Brief.PDF offen!"+CR+LF+"Bitte AdobeReader schlieáen, dann nochmal versuchen!") RETURN .F. ELSE FClose(nHandle) ENDIF ENDIF //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ IF Len(cFile) > 50 cText := cFile cFile := "HTML_Brief" ELSE nHandle := FOpen( cFile, FO_READ ) //09.01.2026 10:46 cBuffer := Space(3000) //cBuffer := Space(10000) //09.01.2026 10:47 nBytes := FRead( nHandle, @cBuffer, 3000 ) //nBytes := FRead( nHandle, @cBuffer, 10000 ) cBuffer := FReadStr( nHandle, 20000 ) cText := AllTrim(cBuffer) FClose( nHandle ) ENDIF // Test mit automatischem Ausfllen bei bestimmtem Formular: IF "KSO_GhAusz.png"$cFormular cFont := "Times New Roman" cFSize := "14pt" cFormSeite := "0cm 0cm 0cm 0cm" nZeileMM := 4.9 cText := CR+LF+CR+LF + Space(65) + "Auftrag: " + Str(1->auftrnr,6,0) + CR+LF+CR+LF+CR+LF+CR+LF+CR+LF+CR+LF cText += Space(35) + Trim(1->vorname) + " " + Trim(1->name) + CR+LF ENDIF IF cFile == "c:\hdbe\dHTML.abr" .OR. cFile == "c:\hdbe\dHTML.mahn" cText := StrTran( cText, CR+LF+" ", CR+LF ) // linken Rand zu NULL machen ENDIF aFormSeite := Split(" ",cFormSeite) //18.02.2026 10:11 Split() ist in DbDruSysw.prg // vermutlich hier berflssig, weil schon in Inditext_1() 08.11.2022 10:42 // cBuero := SubStr(cBU5,At(" ",cBU5)+1) // cRufnummer := cBU6 IF 'Temp'$cFile // 11.12.2022 17:14 wenn im Text Formatierungen vorkommen (bl_r,bl_a etc...) cNeuTxt := ; ''+CR+LF+; ''+CR+LF+; ''+CR+LF+; ' '+CR+LF+; ' '+cFile+''+CR+LF+; ' '+CR+LF+; ' '+CR+LF+; ' '+CR+LF+; ''+CR+LF+; IIf( Upper(Right(cFormular,4))==".PNG", ; '',; '')+CR+LF+; '
'	//+CR+LF+;
	ELSE //!"'+CR+LF+;
         ''+CR+LF+;
         ''+CR+LF+;
         '	'+CR+LF+;
         '	'+cFile+''+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         ''+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
			''+CR+LF+;
			'
'+CR+LF+;
			'
'+CR+LF+; 'Bild1
'+CR+LF+; ''+CR+LF+; '
'+CR+LF, ; ''+CR+LF+; '
'+CR+LF+;
         ''+CR+LF+;
			'
'+CR+LF ) ENDIF /*17.02.2026 20:49 ''+CR+LF+; '
'+CR+LF, ; cNeuTxt := ; ''+CR+LF+; ''+CR+LF+; ''+CR+LF+; ' '+CR+LF+; ' '+cFile+''+CR+LF+; ' '+CR+LF+; ' '+CR+LF+; ' '+CR+LF+; ''+CR+LF+; IIf( Upper(Right(cFormular,4))==".PNG", ; ''+CR+LF+; '
'+CR+LF+;
         '', ;
         ''+CR+LF+;
         '
' )
	ENDIF
*/	
   cNeuTxt += ConvToAnsiCP(cText)
         
   cNeuTxt += '
' //17.02.2026 20:53
wegen ELSE-Žnderung hier oben cNeuTxt := StrTran( cNeuTxt, "", " ") // durch <> entstehen 7 Blanks IF !FExists("c:\hdbe\HTML_Brief.html") nHandle := FCreate("c:\hdbe\HTML_Brief.html") FClose(nHandle) Sleep(100) ENDIF nHandle := FOpen("c:\hdbe\HTML_Brief.html",FO_READWRITE) nBytes := FRead( nHandle, @cBuffer, 20000 ) nBytes := Max(10000,nBytes) FSeek(nHandle, 0) nBytes := FWrite( nHandle, PadR(cNeuTxt,nBytes," ") ) // damit frhere, l„ngere Texte berschrieben werden !!! nBytes := FClose( nHandle ) //15.04.2025 15:46 jetzt ohne die Strg-Taste // IF AppKeyState(65553)==1 .OR. " nFZeit .OR. DATE() > dFDatum ) .AND. .NOT. nZ > 20 sleep(100) cFZeit := Directory("C:\HDBE\HTML_Brief.pdf")[1,F_WRITE_TIME] nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2)) nZ++ ENDDO //05.01.2024 cPPLinks aus: FExists(cDatver+"PdfProgLinks.txt") // speziell fr BleinX, weil ein PC keinen AdobeReader kann IF Len(cPPLinks)>0 FOR n := 1 TO nMaxLines aPPLinks[n] := Trim(MemoLine(cPPLinks, 100, n)) NEXT FOR n := 1 TO Len(aPPLinks) cPPLinks := aPPLinks[n] // cPPLinks wird hier doppelt verwendet ... IF nZ > 20 msgbox("Achtung: Die PDF-Datei ist vermutlich von einem frheren Fall!") BREAK ENDIF IF FExists(cPPLinks) RunShell ("&cFilepdf",cPPLinks,.T.) EXIT ENDIF NEXT IIf(n>len(aPPLinks), msgbox("Das PDF-Programm ist nicht ordentlich installiert!"),) ELSE IF nZ > 20 msgbox("Achtung: Die PDF-DAtei ist vermutlich von einem frheren Fall!") ELSEIF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe') //64bit Reader RunShell ("&cFilepdf","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.) ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe') //32bit Reader RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.) ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe') // Test nur fr BleinX RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe",.T.) ELSE msgbox("Der Adobe Reader DC ist nicht ordentlich installiert!") ENDIF ENDIF ENDIF ELSE msgbox("LibreOffice ist nicht ordentlich installiert") ENDIF ELSE //26.08.2023 20:37 das muss in dieser Reihenfolge (lt. Alaska): RunShell ( "c:\hdbe\HTML_Brief.html","c:\Program Files\LibreOffice\program\swriter.exe",.T.) //01.09.2023 .T. ENDIF IF !Empty(cNotiz_Bez) cVermerk := ConvToOEMCP(cNotiz_Bez) + ": "+DtoC(DATE()) + ", " + BriefAdresse(2,"A") // 2==1-zeilig, "A"==Ansprechpartner IF !cVermerk$1->notiz 1->(DbRlock()) 1->notiz += CRLF + cVermerk 1->(DbCommit()) ENDIF ENDIF RETURN .T. //14.02.2026 12:44 aus FormHtml_2 kopiert, aber den Mail-Schluss original belassen: //aus FUNCTION HTML_Brief_2 fr Inditext_2() //cOrdner = FormArt-Bezeichnung ohne .txt //cMail_Adr = Mail-Adresse aus inditextF.txt 19.11.2023 11:49 //cMail_Betr = Mail-Betreff aus inditextF.txt 19.11.2023 11:49 //14.02.2026 17:53 abgeglichen mit HTML_Form_2 bis zu dieser Linie: (dahinter ist die Mail-Routine) //*******************************************************************************************vvvvvvvvvvvvvv FUNCTION HTML_Form_1( cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez, cOrdner, cFile, cMail_Adr, cMail_Betr) LOCAL nZei := 8, nAnf, nEnd, CR := Chr(13), LF := Chr(10) LOCAL nHandle, cBuffer := Space(10000), nBytes, cText, cNeuTxt := "" LOCAL nFSize, nFHoehe, nFBreite LOCAL nZeileMM LOCAL cSZeit, nSZeit, cFZeit, nFZeit, nZ //30.12.2022 15:29 warten aufs PDF LOCAL cHeute := DtoC(DATE()) LOCAL oProgress //26.10.2023 18:56 LOCAL cMail_Body //21.11.2023 09:47 LOCAL cMailClient := cDatver+"ThunderbirdPortable\ThunderbirdPortable.exe" LOCAL aFormSize, aHtmlFiles, cHFDatum, cVermerk //19.02.2024 15:55 nachtr„glich als LOCAL erkl„rt //05.01.2024 15:33 der Link zum PDF-Programm ist in der Datei PdfProgLinks vvvvvvvvvv LOCAL cTextPP := IIf(FExists(cDatver+"PdfProgLinks.txt"),MemoRead(cDatver+"PdfProgLinks.txt"),"") LOCAL nMaxLines := MlCount(cTextPP, 90) LOCAL aPPLinks[nMaxLines], n LOCAL aParam := {} //14.04.2024 15:56 LOCAL cWhiteMails := "", lMAD_ok := .F. //22.07.2024 12:12 LOCAL cFileVorl //08.04.2025 18:39 der Original-Vorlagen-File als ausfllbare PDF-Datei PRIVATE cPPLinks := cTextPP //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DEFAULT cFormular TO "" DEFAULT cFont TO '"Times New Roman", serif' DEFAULT cFSize TO '18pt' DEFAULT cFormSeite TO '1cm 1cm 1cm 2cm' DEFAULT cZeileCM TO '0.14' //11.10.2022 14:58 Zeilenabstand // PRIVATE cAuftrOrdner := cDatver + "Indiform\AUFTRAG\" + StrZero(1->auftrnr,6,0) // nur bei KSOX PRIVATE cAuftrOrdner := cDatver + "Scans\Dokumente\" + StrZero(1->auftrnr,6,0) // im Ordner der gescannten Dokumente PRIVATE cFilehtml, cFilepdf, cFilehtmlur, cFilepdfur //08.01.2024 10:45 in inditext_1() PRIVATE cBuero //11.10.2022 16:56 PRIVATE fr VariFunkErsatz DEFAULT cMail_Adr TO "" DEFAULT cMail_Betr TO "" PRIVATE cBetreff := cMail_Betr //21.11.2023 10:09 // cFAVp ist PRIVATE = cFAV[1] 05.05.2024 15:08 cMail_Body := IIf(Empty(cMail_Adr),"",VariFunkErsatz_1(MemoRead(cDatver+cFAVp+"\Body.txt"))) //02.01.2024 13:50 nFSize := Val(cFSize) nFHoehe := nFSize * 0.352778 nFBreite := nFSize * 0.2 // 0.2 ist ein gesch„tzter vorl„ufiger Wert nZeileMM := IIf(Val(cZeileCM)<0.2, nFHoehe * Val(cZeileCM)*10, Val(cZeileCM)*10) IF ValType(cFile) == "C" .AND. Len(cFile) > 4 IF Right(Lower(cFile),4) == ".txt" cFile := Stuff(cFile,At(".txt",cFile),4,"") //06.09.2023 19:16 IF "\"$cFile //27.11.2023 12:03 cFile := SubStr(cFile,3) //27.11.2023 12:02 ENDIF ENDIF //07.04.2025 11:05: fr Original-PDFs IF Right(Lower(cFile),4) == ".pdf" cFileVorl := cFile cFile := Stuff(cFile,At(".pdf",Lower(cFile)),4,"") IF "\"$cFile cFile := SubStr(cFile,RAt("\",cFile)+1) ENDIF ENDIF //14.04.2025 17:52: fr Original-ODTs IF Right(Lower(cFile),4) == ".odt" cFileVorl := cFile cFile := Stuff(cFile,At(".odt",Lower(cFile)),4,"") IF "\"$cFile cFile := SubStr(cFile,RAt("\",cFile)+1) ENDIF ENDIF ENDIF IF ValType(cFile)=="C" .AND. Len(cFile)>0 //14.04.2025 14:55 cOrdner := "\" + cFile //06.09.2023 19:16 ELSE RETURN .F. ENDIF cAuftrOrdner += cOrdner //06.09.2023 19:20 IF !FExists( cAuftrOrdner,"D" ) RunShell( "/C MD "+cAuftrOrdner,, .T. ) sleep(200) ENDIF IF !FExists( cAuftrOrdner,"D" ) msgbox("Der Ordner " + cAuftrOrdner + " kann nicht erzeugt werden!") RETURN .F. ENDIF cFilehtml := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + cHeute + ".html" cFilehtmlur := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + "*" + ".html" cFilepdf := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + cHeute + ".pdf" cFilepdfur := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + "*" + ".pdf" IF Upper(cFormular) != "ORIGINAL.PDF" //07.04.2025 19:30 cFormular := Stuff(cFormular,At("\",cFormular),1,"/") aFormSize := FormSize(cFormular) //02.11.2023 10:58 um portrait/landscape zu unterscheiden cFormular := '../../../../' + cFormular ENDIF IF Len(cContainer) == 0 .AND. Len(cFormular) > 0 .AND. !"ORIGINAL.PDF"$Upper(cFormular) //06.04.2025 12:08 wenn nur das Formular gedruckt werden soll ELSEIF !"ORIGINAL.PDF"$Upper(cFormular) //31.10.2023 19:00 wenn kein Original-PDF-Formular // Zur Vermeidung von Kollision verschiedener Drucke vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // Check: ist bereits die Datei cFilehtml auf diesem PC ge”ffnet? IF FExists(cFilehtml) //22.12.2022 19:13 nHandle := FOpen( cFilehtml, FO_EXCLUSIVE ) IF nHandle == -1 //+ Die Datei ist bereits auf diesem PC ge”ffnet FClose(nHandle) msgbox("Es ist bereits ein " + cFilehtml + " offen!"+CR+LF+; "Bitte " + cFilehtml + " im OfficeWriter schlieáen, dann nochmal versuchen!") RETURN .F. ELSEIF ConfirmBox( oCB, "Soll sie berschrieben werden?", ; "Diese Datei ist schon vorhanden mit Datum von heute!", ; XBPMB_YESNO, ; XBPMB_QUESTION ) == XBPMB_RET_YES FClose(nHandle) ELSE FClose(nHandle) RETURN .F. ENDIF ELSEIF FExists(cFilehtmlur) //06.09.2023 11:25 aHtmlFiles := Directory( cFilehtmlur ) ASort(aHtmlFiles,,,{|aX,aY|aX[3]>aY[3]}) //absteigend sortiert nach WriteDatum cHFDatum := SubStr(aHtmlFiles[1,1],RAt("_",aHtmlFiles[1,1])+1,10) // bisher neueste Datei dieser Art IF ConfirmBox( oCB, "Soll sie heute nochmal erzeugt werden?", ; "Diese Datei ist schon vorhanden mit Datum vom "+cHFDatum+"!", ; XBPMB_YESNO, ; XBPMB_QUESTION ) == XBPMB_RET_YES ELSE cFilehtml := Stuff(cFilehtmlur,RAt("_",cFilehtmlur)+1,1,cHFDatum) cFilepdf := Stuff(cFilepdfur,RAt("_",cFilepdfur)+1,1,cHFDatum) ENDIF ENDIF //-------------------------------- // Test: ist bereits die Datei cFilepdf auf diesem PC ge”ffnet? IF FExists(cFilepdf) //22.12.2022 19:13 nHandle := FOpen( cFilepdf, FO_EXCLUSIVE ) IF nHandle = -1 //+ Die Datei ist bereits auf diesem PC ge”ffnet FClose(nHandle) msgbox("Es ist bereits eine Datei " + cFilepdf + " offen!"+CR+LF+; "Bitte AdobeReader schlieáen, dann nochmal versuchen!") RETURN .F. ELSE FClose(nHandle) ENDIF ENDIF ELSE //31.10.2023 19:06 nur fr ORIGINAL.PDF-Formulare: (sofort darstellen) IF FExists(cFilepdfur) cNotiz_Bez := cFile //15.04.2025 19:26 aPDFFiles := Directory( cFilepdfur ) ASort(aPDFFiles,,,{|aX,aY|aX[3]>aY[3]}) //absteigend sortiert nach WriteDatum cHFDatum := SubStr(aPDFFiles[1,1],RAt("_",aPDFFiles[1,1])+1,10) // bisher neueste Datei dieser Art IF ConfirmBox( oCB, "Soll sie heute nochmal erzeugt werden?", ; "Diese Datei ist schon vorhanden mit Datum vom "+cHFDatum+"!", ; XBPMB_YESNO, ; XBPMB_QUESTION ) == XBPMB_RET_YES //13.04.2025 15:56 COPY FILE (cDatver+"F\"+cFile+".pdf") TO (cFilepdf) COPY FILE (cFileVorl) TO (cFilepdf) ELSE //gibts ja hier nicht cFilehtml := Stuff(cFilehtmlur,RAt("_",cFilehtmlur)+1,1,cHFDatum) cFilepdf := Stuff(cFilepdfur,RAt("_",cFilepdfur)+1,1,cHFDatum) ENDIF ENDIF cFilequelle := IIf("ORIGINAL.PDF"$Upper(cFormular), cFileVorl, cDatver+"F\"+cFile+".pdf") //08.04.2025 18:42 ?eigentlich nur: cFileVorl COPY FILE (cFilequelle) TO (cFilepdf) sleep(100) // vorsichtshalber... //06.04.2025 16:32 umgedreht, damit zuerst nach 64bit-Version gesucht wird: IF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe') //64bit Reader RunShell ("&cFilepdf","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.) ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe') //32bit Reader RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.) ELSE msgbox("Der Adobe Reader DC ist nicht ordentlich installiert!") RETURN .F. ENDIF IF !Empty(cNotiz_Bez) cVermerk := ConvToOEMCP(cNotiz_Bez) + ": "+DtoC(DATE()) + ", fr " + BriefAdresse(2,"A") // 2==1-zeilig, "A"==Ansprechpartner IF !cVermerk$1->notiz 1->(DbRlock()) 1->notiz += CRLF + cVermerk 1->(DbCommit()) ENDIF ENDIF RETURN .T. ENDIF //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // X cBuero := SubStr(cBU5,At(" ",cBU5)+1) // X cRufnummer := cBU6 //die Version mit Temp drfte hier eigentlich nie vorkommen ... (06.09.2023 11:28) IF 'Temp'$cFile // 11.12.2022 17:14 wenn im Text Formatierungen vorkommen (bl_r,bl_a etc...) cNeuTxt := ; ''+CR+LF+; ''+CR+LF+; ''+CR+LF+; ' '+CR+LF+; ' '+cFile+''+CR+LF+; ' '+CR+LF+; ' '+CR+LF+; ' '+CR+LF+; ''+CR+LF+; IIf( Upper(Right(cFormular,4))==".PNG", ; '',; '')+CR+LF+; '
'	//+CR+LF+;
	ELSEIF !"'+CR+LF+;
         ''+CR+LF+;
         ''+CR+LF+;
         '	'+CR+LF+;
         '	'+cFile+''+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         ''+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
			''+CR+LF+;
			'
'+CR+LF+;
         ''+CR+LF+;
			'
'+CR+LF+; '
'+CR+LF+; 'Bild1
'+CR+LF, ; ''+CR+LF+; '
'+CR+LF+;
         ''+CR+LF+;
			'
'+CR+LF ) ELSE cNeuTxt := ; ''+CR+LF+; ''+CR+LF+; ''+CR+LF+; ' '+CR+LF+; ' '+cFile+''+CR+LF+; ' '+CR+LF+; ' '+CR+LF+; ' '+CR+LF+; ' '+CR+LF+; ''+CR+LF+; IIf( Upper(Right(cFormular,4))==".PNG", ; ''+CR+LF+; '
'+CR+LF+;
			'
'+CR+LF+; // 21.02.2024 15:10 ohne FORM keine Darstellung von INPUT ... aber ohne mailto: ! '
'+CR+LF+; '
'+CR+LF+; 'Bild1
'+CR+LF, ; ''+CR+LF+; '
'+CR+LF+;
			''+CR+LF+;		// 21.02.2024 15:10 ohne FORM keine Darstellung von INPUT
			'
'+CR+LF ) /* IIf( Upper(Right(cFormular,4))==".PNG", ; ''+CR+LF+; '
'+CR+LF+;
         '', ;
         ''+CR+LF+;
         '
' )
*/
//			'
' )
//			''+CR+LF+;		// (body &) attachment geht bei mailto nicht !!

	ENDIF

	cNeuTxt += ConvToAnsiCP(cContainer)
	IF !"notiz
				1->(DbRlock())
				1->notiz += CRLF + cVermerk
				1->(DbCommit())
			ENDIF
		ENDIF
		
		RETURN .T.
	ENDIF
	
	//19.12.2022 15:13 mit LibreOffice zu PDF konvertieren, wenn Input-Felder enthalten sind:
//	IF AppKeyState(65553)==1 .OR. " 0		// gibt es diese Datei schon mit frherem Zeitstempel von heute?:
					dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
					cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
					nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
					nZ := 0

                  oProgress:increment()      //+26.10.2023 18:59

					DO WHILE (nSZeit > nFZeit .OR. DATE() > dFDatum ) .AND. .NOT. nZ > 20
						sleep(100)
						dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
						cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
						nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
						nZ++

                  oProgress:increment()      //+26.10.2023 18:59

					ENDDO
				ELSE		//05.10.2023 18:14 jetzt Schleife fr erste Datei des Tages
					nZ := 0
					DO WHILE Len(Directory(cFilepdf)) == 0 .AND. .NOT. nZ > 20
                  oProgress:increment()      //+27.11.2023 14:35
						sleep(100)		//16.03.2025 18:27 aus 50 wird 100, weil zu oft nZ>20 ist ("frherer Fall")
						nZ++
					ENDDO
				ENDIF

         oProgress:destroy()      //+26.10.2023 18:59
				
				//05.01.2024 cPPLinks aus: FExists(cDatver+"PdfProgLinks.txt")
				// speziell fr BleinX, weil ein PC keinen AdobeReader kann
				IF Len(cPPLinks)>0	
					FOR n := 1 TO nMaxLines
						aPPLinks[n] := Trim(MemoLine(cPPLinks, 100, n))
					NEXT
					FOR n := 1 TO Len(aPPLinks)
						cPPLinks := aPPLinks[n]	// cPPLinks wird hier doppelt verwendet ...
						IF nZ > 20
							msgbox("Achtung: Die PDF-Datei ist vermutlich von einem frheren Fall!")
							BREAK
						ENDIF
						IF FExists(cPPLinks)
							RunShell ("&cFilepdf",cPPLinks,.T.)
							EXIT
						ENDIF
					NEXT
					IIf(n>len(aPPLinks), msgbox("Das PDF-Programm ist nicht ordentlich installiert!"),)
				ELSE
					IF nZ > 20
						msgbox("Achtung: Die PDF-DAtei ist vermutlich von einem frheren Fall!")
					ELSEIF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe')							//64bit Reader
						RunShell ("&cFilepdf","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.)
					ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe')		//32bit Reader
						RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.)
					ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe')			// Test nur fr BleinX
						RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe",.T.)
					ELSE
						msgbox("Der Adobe Reader DC ist nicht ordentlich installiert!")
					ENDIF
				ENDIF
			ENDIF
		ELSE
			msgbox("LibreOffice ist nicht ordentlich installiert")
		ENDIF
	ELSE	// wenn keine Input-Felder enthalten, dann mit dem LO-Writer ”ffnen:
		//26.08.2023 20:37 das muss in dieser Reihenfolge (lt. Alaska):
		//** RunShell ( "&cFilehtml","c:\Program Files\LibreOffice\program\swriter.exe")
		RunShell ( '&cFilehtml macro:///Standard.Module1.xRechPDF ','c:\Program Files\LibreOffice\program\swriter.exe')
	ENDIF

//*******************************************************************************************vvvvvvvvvvvvvv
//14.02.2026 12:44 ab hier aus dem html_form_1_original:

	//21.11.2023 16:23 Mail mit Anhang senden aus dem Programm, weil ...
	//						... weil mit mailto: aus dem Formular kein Attachment zu mailen geht!!
	//*** verhindern, dass KSO mailen kann: (hat offiziell keinen Internet-Anschluss!!)***
	// IF .NOT. Upper(AppName())$"KSOX.EXE" am 02.01.2024 13:15
	IF !"KSOX"$Upper(AppName()) .AND. ConfirmBox( oCB, "Ggf. vorher ausfllen und dann:"+CRLF+;
							"mailen = Ja --- abbrechen = NEIN", ;
                     "M”chten Sie das Formular mailen an "+cMail_Adr+"?", ;
                     XBPMB_YESNO, ;
                     XBPMB_QUESTION ) == XBPMB_RET_YES
//27.11.2023 12:35  vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
		IF !" krzen:^
		   nHandle := FCreate(cFilehtml)
		   nBytes := FWrite( nHandle, cNeuTxt )
		   nBytes := FClose( nHandle )
			sleep(50)
	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	      //+26.10.2023 18:57 Fortschrittsanzeige
	      oProgress := ProgressBar():new( AppDeskTop(),, {400,350}, {AppDeskTop():currentsize()[1]-800,24},, .F. )
	      oProgress:create()
	      oProgress:color   := GRA_CLR_GREEN
	      oProgress:minimum := 1
	      oProgress:maximum := 20
			RunShell (' --headless --convert-to pdf:"writer_pdf_Export" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
				IF Len(Directory(cFilepdf)) > 0		// gibt es diese Datei schon mit frherem Zeitstempel von heute?:
					dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
					cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
					nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
					nZ := 0

                  oProgress:increment()      //+26.10.2023 18:59

					DO WHILE (nSZeit > nFZeit .OR. DATE() > dFDatum ) .AND. .NOT. nZ > 20
						sleep(100)
						dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
						cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
						nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
						nZ++

                  oProgress:increment()      //+26.10.2023 18:59

					ENDDO
				ELSE		//05.10.2023 18:14 jetzt Schleife fr erste Datei des Tages
					nZ := 0
					DO WHILE Len(Directory(cFilepdf)) == 0 .AND. .NOT. nZ > 20
                  oProgress:increment()      //+27.11.2023 14:35
						sleep(50)
						nZ++
					ENDDO
				ENDIF
         oProgress:destroy()      //+26.10.2023 18:59
		ENDIF
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	   Runshell( [-compose "to=']+cMail_Adr+[',subject=']+cMail_Betr+[',body=']+cMail_Body+[',attachment=']+cFilePDF+['"], cMailClient, .T. ) //18.09.2020 09:39 von .F. auf .T., weil bei Sonnex Vorschau einfriert...
	ELSEIF !Upper(AppName())$"KSOX.EXE"		//02.01.2024 13:15
		RETURN .T.
	ENDIF

   IF !Empty(cNotiz_Bez)
      cVermerk := ConvToOEMCP(cNotiz_Bez) + ": "+DtoC(DATE()) + ", " + BriefAdresse(2,"A")	// 2==1-zeilig, "A"==Ansprechpartner
	   IF !cVermerk$1->notiz
	      1->(DbRlock())
	      1->notiz += CRLF + cVermerk
	      1->(DbCommit())
	   ENDIF
	ENDIF
RETURN .T.


//aus FUNCTION HTML_Brief_1 fr Inditext_1()
//cOrdner = FormArt-Bezeichnung ohne .txt
//cMail_Adr = Mail-Adresse aus inditextF.txt	19.11.2023 11:49
//cMail_Betr = Mail-Betreff aus inditextF.txt	19.11.2023 11:49
FUNCTION HTML_Form_1_original( cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez, cOrdner, cFile, cMail_Adr, cMail_Betr)	
   LOCAL nZei := 8, nAnf, CR := Chr(13), LF := Chr(10)
   LOCAL nHandle, cBuffer := Space(10000), nBytes, cText, cNeuTxt := ""
   LOCAL nFSize, nFHoehe, nFBreite
   LOCAL nZeileMM
   LOCAL cSZeit, nSZeit, cFZeit, nFZeit, nZ	//30.12.2022 15:29 warten aufs PDF
   LOCAL cHeute := DtoC(DATE())
   LOCAL oProgress	//26.10.2023 18:56
   LOCAL cMail_Body	//21.11.2023 09:47
   LOCAL cMailClient := cDatver+"ThunderbirdPortable\ThunderbirdPortable.exe"
   LOCAL aFormSize, aHtmlFiles, cHFDatum, cVermerk		//19.02.2024 15:55 nachtr„glich als LOCAL erkl„rt
	//05.01.2024 15:33 der Link zum PDF-Programm ist in der Datei PdfProgLinks vvvvvvvvvv
	LOCAL cTexte := IIf(FExists(cDatver+"PdfProgLinks.txt"),MemoRead(cDatver+"PdfProgLinks.txt"),"")
	LOCAL nMaxLines := MlCount(cTexte, 90)
	LOCAL aPPLinks[nMaxLines], n
	PRIVATE cPPLinks := cTexte
	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   DEFAULT cFormular TO ""
   DEFAULT cFont TO '"Times New Roman", serif'
   DEFAULT cFSize TO '18pt'
   DEFAULT cFormSeite TO '1cm 1cm 1cm 2cm'
   DEFAULT cZeileCM TO '0.14'		//11.10.2022 14:58 Zeilenabstand
//	PRIVATE cAuftrOrdner := cDatver + "Indiform\AUFTRAG\" + StrZero(1->auftrnr,6,0)	// nur bei KSOX
	PRIVATE cAuftrOrdner := cDatver + "Scans\Dokumente\" + StrZero(1->auftrnr,6,0)	// im Ordner der gescannten Dokumente
   PRIVATE cFilehtml, cFilepdf, cFilehtmlur, cFilepdfur
//08.01.2024 10:45 in inditext_1()	PRIVATE cBuero						//11.10.2022 16:56 PRIVATE fr VariFunkErsatz
	DEFAULT cMail_Adr TO ""
	DEFAULT cMail_Betr TO ""
	PRIVATE cBetreff := cMail_Betr	//21.11.2023 10:09
   cMail_Body := IIf(Empty(cFormular),"",VariFunkErsatz_1(MemoRead(cDatver+cFormular[1]+"\Body.txt")))	//02.01.2024 13:50

	
   nFSize := Val(cFSize)
   nFHoehe := nFSize * 0.352778
   nFBreite := nFSize * 0.2	// 0.2 ist ein gesch„tzter vorl„ufiger Wert 
   nZeileMM := IIf(Val(cZeileCM)<0.2, nFHoehe * Val(cZeileCM)*10, Val(cZeileCM)*10)
	
	IF ".txt"$cFile
		cFile := Stuff(cFile,At(".txt",cFile),4,"")	//06.09.2023 19:16
		IF "\"$cFile	//27.11.2023 12:03
			cFile := SubStr(cFile,3)		//27.11.2023 12:02
		ENDIF
	ENDIF
	cOrdner := "\" + cFile		//06.09.2023 19:16
	cAuftrOrdner += cOrdner		//06.09.2023 19:20
	
   IF !FExists( cAuftrOrdner,"D" )
      RunShell( "/C MD "+cAuftrOrdner,, .T. )
      sleep(100)
   ENDIF
   IF !FExists( cAuftrOrdner,"D" )
		msgbox("Der Ordner " + 	cAuftrOrdner + " kann nicht erzeugt werden!")
		RETURN .F.
	ENDIF
	
	cFilehtml := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + cHeute + ".html"
	cFilehtmlur := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + "*" + ".html"
	cFilepdf := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + cHeute + ".pdf"
	cFilepdfur := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + "*" + ".pdf"
	
	cFormular := Stuff(cFormular,At("\",cFormular),1,"/")
	aFormSize := FormSize(cFormular)	//02.11.2023 10:58	um portrait/landscape zu unterscheiden
	cFormular := '../../../../' + cFormular
	
	IF !"ORIGINAL.PDF"$Upper(cFormular)	//31.10.2023 19:00 wenn kein Original-PDF-Formular
		// Zur Vermeidung von Kollision verschiedener Drucke    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
		// Check: ist bereits die Datei cFilehtml auf diesem PC ge”ffnet?
		IF FExists(cFilehtml)		//22.12.2022 19:13
			nHandle := FOpen( cFilehtml, FO_EXCLUSIVE )
			IF nHandle = -1
			   //+ Die Datei ist bereits auf diesem PC ge”ffnet
			   FClose(nHandle)
			   msgbox("Es ist bereits ein " + cFilehtml + " offen!"+CR+LF+;
			   			"Bitte " + cFilehtml + " im OfficeWriter schlieáen, dann nochmal versuchen!")
			   RETURN .F.
			ELSEIF ConfirmBox( oCB, "Soll sie berschrieben werden?", ;
	                        "Diese Datei ist schon vorhanden mit Datum von heute!", ;
	                        XBPMB_YESNO, ;
	                        XBPMB_QUESTION ) == XBPMB_RET_YES
			   FClose(nHandle)
			ELSE 
			   FClose(nHandle)
			   RETURN .F.
			ENDIF
		ELSEIF FExists(cFilehtmlur)		//06.09.2023 11:25
	      aHtmlFiles := Directory( cFilehtmlur )
			ASort(aHtmlFiles,,,{|aX,aY|aX[3]>aY[3]})		//absteigend sortiert nach WriteDatum
			cHFDatum := SubStr(aHtmlFiles[1,1],RAt("_",aHtmlFiles[1,1])+1,10)	// bisher neueste Datei dieser Art
					
			IF ConfirmBox( oCB, "Soll sie heute nochmal erzeugt werden?", ;
	                        "Diese Datei ist schon vorhanden mit Datum vom "+cHFDatum+"!", ;
	                        XBPMB_YESNO, ;
	                        XBPMB_QUESTION ) == XBPMB_RET_YES
			ELSE
				cFilehtml := Stuff(cFilehtmlur,RAt("_",cFilehtmlur)+1,1,cHFDatum)
				cFilepdf := Stuff(cFilepdfur,RAt("_",cFilepdfur)+1,1,cHFDatum)
			ENDIF
		ENDIF
		//--------------------------------
		
		// Test: ist bereits die Datei cFilepdf auf diesem PC ge”ffnet?
		IF FExists(cFilepdf)		//22.12.2022 19:13
			nHandle := FOpen( cFilepdf, FO_EXCLUSIVE )
			IF nHandle = -1
			   //+ Die Datei ist bereits auf diesem PC ge”ffnet
			   FClose(nHandle)
			   msgbox("Es ist bereits eine Datei " + cFilepdf + " offen!"+CR+LF+;
			   			"Bitte AdobeReader schlieáen, dann nochmal versuchen!")
			   RETURN .F.
			ELSE
			   FClose(nHandle)
			ENDIF
		ENDIF
	ELSE		//31.10.2023 19:06 nur fr ORIGINAL.PDF-Formulare: (sofort darstellen)
		cFilepdf := SubStr(cFormular,13)
		IF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe')
			RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.)
		ELSEIF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe')
			RunShell ("&cFilepdf","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.)
		ELSE
			msgbox("Der Adobe Reader DC ist nicht ordentlich installiert!")
			RETURN .F.
		ENDIF
	   IF !Empty(cNotiz_Bez)
	      cVermerk := ConvToOEMCP(cNotiz_Bez) + ": "+DtoC(DATE()) + ", " + BriefAdresse(2,"A")	// 2==1-zeilig, "A"==Ansprechpartner
		   IF !cVermerk$1->notiz
		      1->(DbRlock())
		      1->notiz += CRLF + cVermerk
		      1->(DbCommit())
		   ENDIF
		ENDIF
		RETURN .T.
	ENDIF
	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

// X  cBuero := SubStr(cBU5,At(" ",cBU5)+1)
// X  cRufnummer := cBU6

	//die Version mit Temp drfte hier eigentlich nie vorkommen ... (06.09.2023 11:28)
	IF 'Temp'$cFile	// 11.12.2022 17:14 wenn im Text Formatierungen vorkommen (bl_r,bl_a etc...)
	   cNeuTxt := ;
         ''+CR+LF+;
         ''+CR+LF+;
         ''+CR+LF+;
         '	'+CR+LF+;
         '	'+cFile+''+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         ''+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
         '',;
         '')+CR+LF+;
         '
'	//+CR+LF+;
	ELSEIF !"'+CR+LF+;
         ''+CR+LF+;
         ''+CR+LF+;
         '	'+CR+LF+;
         '	'+cFile+''+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         ''+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
         ''+CR+LF+;
         '
'+CR+LF+;
         '', ;
         ''+CR+LF+;
         '
' )
	ELSE
/*         ''+CR+LF+;*/
	   cNeuTxt := ;
         ''+CR+LF+;
			''+CR+LF+;
         ''+CR+LF+;
         '	'+CR+LF+;
         '	'+cFile+''+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         '	'+CR+LF+;
         ''+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
			''+CR+LF+;
			'
'+CR+LF+;
			''+CR+LF+;		// (body &) attachment geht bei mailto nicht !!
			'
'+CR+LF+; '
'+CR+LF+; 'Bild1
'+CR+LF, ; ''+CR+LF+; '
'+CR+LF+;
			''+CR+LF+;		// 21.02.2024 15:10 ohne FORM keine Darstellung von INPUT
			'
'+CR+LF ) //mit Flex: '
'+CR+LF+; //ohne Flex: '
'+CR+LF+; // '
' )

	ENDIF
//			''+CR+LF+;
//			''+CR+LF+;

   cNeuTxt += ConvToAnsiCP(cContainer)
	IF !" 0		// gibt es diese Datei schon mit frherem Zeitstempel von heute?:
					dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
					cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
					nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
					nZ := 0

                  oProgress:increment()      //+26.10.2023 18:59

					DO WHILE (nSZeit > nFZeit .OR. DATE() > dFDatum ) .AND. .NOT. nZ > 20
						sleep(100)
						dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
						cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
						nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
						nZ++

                  oProgress:increment()      //+26.10.2023 18:59

					ENDDO
				ELSE		//05.10.2023 18:14 jetzt Schleife fr erste Datei des Tages
					nZ := 0
					DO WHILE Len(Directory(cFilepdf)) == 0 .AND. .NOT. nZ > 20
                  oProgress:increment()      //+27.11.2023 14:35
						sleep(50)
						nZ++
					ENDDO
				ENDIF

         oProgress:destroy()      //+26.10.2023 18:59
				
				//05.01.2024 cPPLinks aus: FExists(cDatver+"PdfProgLinks.txt")
				// speziell fr BleinX, weil ein PC keinen AdobeReader kann
				IF Len(cPPLinks)>0	
					FOR n := 1 TO nMaxLines
						aPPLinks[n] := Trim(MemoLine(cPPLinks, 100, n))
					NEXT
					FOR n := 1 TO Len(aPPLinks)
						cPPLinks := aPPLinks[n]	// cPPLinks wird hier doppelt verwendet ...
						IF nZ > 20
							msgbox("Achtung: Die PDF-Datei ist vermutlich von einem frheren Fall!")
							BREAK
						ENDIF
						IF FExists(cPPLinks)
							RunShell ("&cFilepdf",cPPLinks,.T.)
							EXIT
						ENDIF
					NEXT
					IIf(n>len(aPPLinks), msgbox("Das PDF-Programm ist nicht ordentlich installiert!"),)
				ELSE
					IF nZ > 20
						msgbox("Achtung: Die PDF-DAtei ist vermutlich von einem frheren Fall!")
					ELSEIF AppKeyState(65553)==1 .AND. FExists('C:\Program Files\LibreOffice\program\sdraw.exe')
					//21.12.2023 19:09 mit Strg-Taste:
						RunShell ("&cFilehtml","C:\Program Files\LibreOffice\program\sdraw.exe",.T.)
					ELSEIF AppKeyState(65554)==1 .AND. FExists('C:\CS2\Adobe\Acrobat 7.0\Acrobat\Acrobat.exe')
					//21.12.2023 19:09 mit Alt-Taste:
						RunShell ("&cFilepdf","C:\CS2\Adobe\Acrobat 7.0\Acrobat\Acrobat.exe",.T.)
					ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe')
						RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.)
					ELSEIF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe')
						RunShell ("&cFilepdf","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.)
					ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe')
						RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe",.T.)
					ELSE
						msgbox("Der Adobe Reader DC ist nicht ordentlich installiert!")
					ENDIF
				ENDIF
			ENDIF
		ELSE
			msgbox("LibreOffice ist nicht ordentlich installiert")
		ENDIF
	ELSE
		//26.08.2023 20:37 das muss in dieser Reihenfolge (lt. Alaska):
		RunShell ( "&cFilehtml","c:\Program Files\LibreOffice\program\swriter.exe")
	ENDIF

	//21.11.2023 16:23 Mail mit Anhang senden aus dem Programm, weil ...
	//						... weil mit mailto: aus dem Formular kein Attachment zu mailen geht!!
	//*** verhindern, dass KSO mailen kann: (hat offiziell keinen Internet-Anschluss!!)***
	// IF .NOT. Upper(AppName())$"KSOX.EXE" am 02.01.2024 13:15
	IF !"KSOX"$Upper(AppName()) .AND. ConfirmBox( oCB, "Ggf. vorher ausfllen und dann:"+CRLF+;
							"mailen = Ja --- abbrechen = NEIN", ;
                     "M”chten Sie das Formular mailen an "+cMail_Adr+"?", ;
                     XBPMB_YESNO, ;
                     XBPMB_QUESTION ) == XBPMB_RET_YES
//27.11.2023 12:35  vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
		IF !" krzen:^
		   nHandle := FCreate(cFilehtml)
		   nBytes := FWrite( nHandle, cNeuTxt )
		   nBytes := FClose( nHandle )
			sleep(50)
	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	      //+26.10.2023 18:57 Fortschrittsanzeige
	      oProgress := ProgressBar():new( AppDeskTop(),, {400,350}, {AppDeskTop():currentsize()[1]-800,24},, .F. )
	      oProgress:create()
	      oProgress:color   := GRA_CLR_GREEN
	      oProgress:minimum := 1
	      oProgress:maximum := 20
			RunShell (' --headless --convert-to pdf:"writer_pdf_Export" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
				IF Len(Directory(cFilepdf)) > 0		// gibt es diese Datei schon mit frherem Zeitstempel von heute?:
					dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
					cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
					nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
					nZ := 0

                  oProgress:increment()      //+26.10.2023 18:59

					DO WHILE (nSZeit > nFZeit .OR. DATE() > dFDatum ) .AND. .NOT. nZ > 20
						sleep(100)
						dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
						cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
						nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
						nZ++

                  oProgress:increment()      //+26.10.2023 18:59

					ENDDO
				ELSE		//05.10.2023 18:14 jetzt Schleife fr erste Datei des Tages
					nZ := 0
					DO WHILE Len(Directory(cFilepdf)) == 0 .AND. .NOT. nZ > 20
                  oProgress:increment()      //+27.11.2023 14:35
						sleep(50)
						nZ++
					ENDDO
				ENDIF
         oProgress:destroy()      //+26.10.2023 18:59
		ENDIF
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	   Runshell( [-compose "to=']+cMail_Adr+[',subject=']+cMail_Betr+[',body=']+cMail_Body+[',attachment=']+cFilePDF+['"], cMailClient, .T. ) //18.09.2020 09:39 von .F. auf .T., weil bei Sonnex Vorschau einfriert...
	ELSEIF !Upper(AppName())$"KSOX.EXE"		//02.01.2024 13:15
		RETURN .T.
	ENDIF

   IF !Empty(cNotiz_Bez)
      cVermerk := ConvToOEMCP(cNotiz_Bez) + ": "+DtoC(DATE()) + ", " + BriefAdresse(2,"A")	// 2==1-zeilig, "A"==Ansprechpartner
	   IF !cVermerk$1->notiz
	      1->(DbRlock())
	      1->notiz += CRLF + cVermerk
	      1->(DbCommit())
	   ENDIF
	ENDIF
RETURN .T.

//aus FUNCTION HTML_Brief_1 fr Inditext_1()
//cOrdner = FormArt-Bezeichnung ohne .txt
//cMail_Adr = Mail-Adresse aus inditextF.txt	19.11.2023 11:49
//cMail_Betr = Mail-Betreff aus inditextF.txt	19.11.2023 11:49
FUNCTION ODT_Form_1( cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez, cOrdner, cFile, cMail_Adr, cMail_Betr)	
   LOCAL nZei := 8, nAnf, CR := Chr(13), LF := Chr(10)
   LOCAL nHandle, cBuffer := Space(10000), nBytes, cText, cNeuTxt := ""
   LOCAL nFSize, nFHoehe, nFBreite
   LOCAL nZeileMM
   LOCAL cSZeit, nSZeit, cFZeit, nFZeit, nZ	//30.12.2022 15:29 warten aufs PDF
   LOCAL cHeute := DtoC(DATE())
   LOCAL oProgress	//26.10.2023 18:56
   LOCAL cMail_Body	//21.11.2023 09:47
   LOCAL cMailClient := cDatver+"ThunderbirdPortable\ThunderbirdPortable.exe"
   LOCAL aFormSize, aODTFiles, cHFDatum, cVermerk		//19.02.2024 15:55 nachtr„glich als LOCAL erkl„rt
	//18.02.2026 13:12 der Link zum PDF-Programm ist in der Datei PdfProgLinks vvvvvvvvvv
	LOCAL cTextPP := IIf(FExists(cDatver+"PdfProgLinks.txt"),MemoRead(cDatver+"PdfProgLinks.txt"),"")
	LOCAL nMaxLines := MlCount(cTextPP, 90)		//18.02.2026 13:12
	LOCAL aPPLinks[nMaxLines], n					//18.02.2026 13:12
   DEFAULT cFormular TO ""
   DEFAULT cFont TO '"Times New Roman", serif'
   DEFAULT cFSize TO '18pt'
   DEFAULT cFormSeite TO '1cm 1cm 1cm 2cm'
   DEFAULT cZeileCM TO '0.14'		//11.10.2022 14:58 Zeilenabstand
//	PRIVATE cAuftrOrdner := cDatver + "Indiform\AUFTRAG\" + StrZero(1->auftrnr,6,0)	// nur bei KSOX
	PRIVATE cAuftrOrdner := cDatver + "Scans\Dokumente\" + StrZero(1->auftrnr,6,0)	// im Ordner der gescannten Dokumente
   PRIVATE cFileODT, cFilepdf, cFileODTur, cFilepdfur
//08.01.2024 10:45 in inditext_1()	PRIVATE cBuero						//11.10.2022 16:56 PRIVATE fr VariFunkErsatz
	DEFAULT cMail_Adr TO ""
	DEFAULT cMail_Betr TO ""
	PRIVATE cBetreff := cMail_Betr	//21.11.2023 10:09
	PRIVATE cFilequelle := IIf(FExists("C:\HDBE\"+cFile),"C:\HDBE\"+cFile,cDatver+cFile)
	PRIVATE cPPLinks := cTextPP	//18.02.2026 13:12
   cMail_Body := IIf(Empty(cFormular),"",VariFunkErsatz_1(MemoRead(cDatver+cFormular[1]+"\Body.txt")))	//02.01.2024 13:50

/*	
   nFSize := Val(cFSize)
   nFHoehe := nFSize * 0.352778
   nFBreite := nFSize * 0.2	// 0.2 ist ein gesch„tzter vorl„ufiger Wert 
   nZeileMM := IIf(Val(cZeileCM)<0.2, nFHoehe * Val(cZeileCM)*10, Val(cZeileCM)*10)
*/	
	IF ".ODT"$Upper(cFile)
		cFile := Stuff(cFile,At(".ODT",Upper(cFile)),4,"")	//06.09.2023 19:16
		IF "\"$cFile	//27.11.2023 12:03	F\,A\,V\
			cFile := SubStr(cFile,3)		//27.11.2023 12:02
		ENDIF
	ENDIF
	cOrdner := "\" + cFile		//06.09.2023 19:16
	cAuftrOrdner += cOrdner		//06.09.2023 19:20
	
   IF !FExists( cAuftrOrdner,"D" )
      RunShell( "/C MD "+cAuftrOrdner,, .T. )
		Sleep(200)
   ENDIF
   IF !FExists( cAuftrOrdner,"D" )
		msgbox("Der Ordner " + 	cAuftrOrdner + " kann nicht erzeugt werden!")
		RETURN .F.
	ENDIF
	
	cFileodt := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + cHeute + ".odt"
	cFileodtur := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + "*" + ".odt"
	cFilepdf := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + cHeute + ".pdf"
	cFilepdfur := cAuftrOrdner + "\" + cFile + "_" + StrZero(1->auftrnr,6,0) + "_" + "*" + ".pdf"
	
//	COPY FILE (cFilequelle) TO (cFileodt)
//	Sleep(200)	//22.03.2024 09:09
	
/*	
	cFormular := Stuff(cFormular,At("\",cFormular),1,"/")
	aFormSize := FormSize(cFormular)	//02.11.2023 10:58	um portrait/landscape zu unterscheiden
	cFormular := '../../../../' + cFormular
*/	
//	IF !"ORIGINAL.PDF"$Upper(cFormular)	//31.10.2023 19:00 wenn kein Original-PDF-Formular
		// Zur Vermeidung von Kollision verschiedener Drucke    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
		// Check: ist bereits die Datei cFilehtml auf diesem PC ge”ffnet?
		IF FExists(cFileodt)		//22.12.2022 19:13

	      aODTFiles := Directory( cFileODTur )
			ASort(aODTFiles,,,{|aX,aY|aX[3]>aY[3]})		//absteigend sortiert nach WriteDatum
			cHFDatum := SubStr(aODTFiles[1,1],RAt("_",aODTFiles[1,1])+1,10)	// bisher neueste Datei dieser Art

			nHandle := FOpen( cFileodt, FO_EXCLUSIVE )
			IF nHandle = -1
			   //+ Die Datei ist bereits auf diesem PC ge”ffnet
			   FClose(nHandle)
			   msgbox("Es ist bereits ein " + cFileodt + " offen!"+CR+LF+;
			   			"Bitte " + cFileodt + " im OfficeWriter schlieáen, dann nochmal versuchen!")
			   RETURN .F.
			ELSEIF Time()>aODTFiles[1][8] .AND. ConfirmBox( oCB, "Soll sie berschrieben werden?", ;
	                        "Diese Datei ist schon vorhanden mit Datum von heute!", ;
	                        XBPMB_YESNO, ;
	                        XBPMB_QUESTION ) == XBPMB_RET_YES		//27.02.2024 20:45 Time()
			   FClose(nHandle)
			   //24.03.2024 20:56 hierher von oben:
				COPY FILE (cFilequelle) TO (cFileodt)
			   Sleep(200)	//22.03.2024 09:09
			ELSE 
			   FClose(nHandle)
			   RETURN .F.
			ENDIF
		ELSEIF FExists(cFileodtur)		//06.09.2023 11:25
	      aODTFiles := Directory( cFileODTur )
			ASort(aODTFiles,,,{|aX,aY|aX[3]>aY[3]})		//absteigend sortiert nach WriteDatum
			cHFDatum := SubStr(aODTFiles[1,1],RAt("_",aODTFiles[1,1])+1,10)	// bisher neueste Datei dieser Art
					
			IF ConfirmBox( oCB, "Soll sie heute nochmal erzeugt werden?", ;
	                        "Diese Datei ist schon vorhanden mit Datum vom "+cHFDatum+"!", ;
	                        XBPMB_YESNO, ;
	                        XBPMB_QUESTION ) == XBPMB_RET_YES
				// 24.03.2024 20:58 hierher von oben:
				COPY FILE (cFilequelle) TO (cFileodt)
			   Sleep(200)	//22.03.2024 09:09
			ELSE
				cFileODT := Stuff(cFileODTur,RAt("_",cFileODTur)+1,1,cHFDatum)
				cFilepdf := Stuff(cFilepdfur,RAt("_",cFilepdfur)+1,1,cHFDatum)
				// 24.03.2024 20:58 hierher von oben:
				COPY FILE (cFilequelle) TO (cFileodt)
			   Sleep(200)	//22.03.2024 09:09
			ENDIF
		ELSE	// wenn cFileODT noch nicht existiert
			// 24.03.2024 20:58 hierher von oben:
			COPY FILE (cFilequelle) TO (cFileodt)
		   Sleep(200)	//22.03.2024 09:09
		ENDIF
		//--------------------------------
		
		// Test: ist bereits die Datei cFilepdf auf diesem PC ge”ffnet?
		IF FExists(cFilepdf)		//22.12.2022 19:13
			nHandle := FOpen( cFilepdf, FO_EXCLUSIVE )
			IF nHandle = -1
			   //+ Die Datei ist bereits auf diesem PC ge”ffnet
			   FClose(nHandle)
			   msgbox("Es ist bereits eine Datei " + cFilepdf + " offen!"+CR+LF+;
			   			"Bitte AdobeReader schlieáen, dann nochmal versuchen!")
			   RETURN .F.
			ELSE
			   FClose(nHandle)
			ENDIF
		ENDIF
/*	ELSE		//31.10.2023 19:06 nur fr ORIGINAL.PDF-Formulare: (sofort darstellen)
		cFilepdf := SubStr(cFormular,13)
		IF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe')
			RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.)
		ELSEIF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe')
			RunShell ("&cFilepdf","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.)
		ELSE
			msgbox("Der Adobe Reader DC ist nicht ordentlich installiert!")
			RETURN .F.
		ENDIF
	   IF !Empty(cNotiz_Bez)
	      cVermerk := ConvToOEMCP(cNotiz_Bez) + ": "+DtoC(DATE()) + ", " + BriefAdresse(2,"A")	// 2==1-zeilig, "A"==Ansprechpartner
		   IF !cVermerk$1->notiz
		      1->(DbRlock())
		      1->notiz += CRLF + cVermerk
		      1->(DbCommit())
		   ENDIF
		ENDIF
		RETURN .T.
	ENDIF
*/	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

	IF AppKeyState(65553)==1 .OR. " 0		// gibt es diese Datei schon mit frherem Zeitstempel von heute?:
					dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
					cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
					nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
					nZ := 0

                  oProgress:increment()      //+26.10.2023 18:59

					DO WHILE (nSZeit > nFZeit .OR. DATE() > dFDatum ) .AND. .NOT. nZ > 20
						sleep(100)
						dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
						cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
						nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
						nZ++

                  oProgress:increment()      //+26.10.2023 18:59

					ENDDO
				ELSE		//05.10.2023 18:14 jetzt Schleife fr erste Datei des Tages
					nZ := 0
					DO WHILE Len(Directory(cFilepdf)) == 0 .AND. .NOT. nZ > 20
                  oProgress:increment()      //+27.11.2023 14:35
						sleep(50)
						nZ++
					ENDDO
				ENDIF

         oProgress:destroy()      //+26.10.2023 18:59
				
				//05.01.2024 cPPLinks aus: FExists(cDatver+"PdfProgLinks.txt")
				// speziell fr BleinX, weil ein PC keinen AdobeReader kann
				IF Len(cPPLinks)>0	
					FOR n := 1 TO nMaxLines
						aPPLinks[n] := Trim(MemoLine(cPPLinks, 100, n))
					NEXT
					FOR n := 1 TO Len(aPPLinks)
						cPPLinks := aPPLinks[n]	// cPPLinks wird hier doppelt verwendet ...
						IF nZ > 20
							msgbox("Achtung: Die PDF-Datei ist vermutlich von einem frheren Fall!")
							BREAK
						ENDIF
						IF FExists(cPPLinks)
							RunShell ("&cFilepdf",cPPLinks,.T.)
							EXIT
						ENDIF
					NEXT
					IIf(n>len(aPPLinks), msgbox("Das PDF-Programm ist nicht ordentlich installiert!"),)
				ELSE
					IF nZ > 20
						msgbox("Achtung: Die PDF-DAtei ist vermutlich von einem frheren Fall!")
					ELSEIF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe')							//64bit Reader
						RunShell ("&cFilepdf","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.)
					ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe')		//32bit Reader
						RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.)
					ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe')			// Test nur fr BleinX
						RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe",.T.)
					ELSE
						msgbox("Der Adobe Reader DC ist nicht ordentlich installiert!")
					ENDIF
				ENDIF
			ENDIF
		ELSE
			msgbox("LibreOffice ist nicht ordentlich installiert")
		ENDIF
	ELSE
		//26.08.2023 20:37 das muss in dieser Reihenfolge (lt. Alaska):
		RunShell ( "&cFileODT","c:\Program Files\LibreOffice\program\swriter.exe",.T.)
//		RunShell ( "--print-to-file &cFileODT --headless","c:\Program Files\LibreOffice\program\swriter.exe",.T.)
//		RunShell ( "--print-to-file &cFileODT --printer-name 'Epsom Universal Print Driver' --outdir /HDBE/F/DRUCK --headless","c:\Program Files\LibreOffice\program\swriter.exe",.T.)
	ENDIF

	//21.11.2023 16:23 Mail mit Anhang senden aus dem Programm, weil ...
	//						... weil mit mailto: aus dem Formular kein Attachment zu mailen geht!!
	//*** verhindern, dass KSO mailen kann: (hat offiziell keinen Internet-Anschluss!!)***
	// IF .NOT. Upper(AppName())$"KSOX.EXE" am 02.01.2024 13:15
	IF !"KSOX"$Upper(AppName()) .AND. ConfirmBox( oCB, "Ggf. vorher ausfllen und dann:"+CRLF+;
							"mailen = Ja --- abbrechen = NEIN", ;
                     "M”chten Sie das Formular mailen an "+cMail_Adr+"?", ;
                     XBPMB_YESNO, ;
                     XBPMB_QUESTION ) == XBPMB_RET_YES
//27.11.2023 12:35  vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
		IF !" krzen:^
		   nHandle := FCreate(cFilehtml)
		   nBytes := FWrite( nHandle, cNeuTxt )
		   nBytes := FClose( nHandle )
			sleep(50)
	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	      //+26.10.2023 18:57 Fortschrittsanzeige
	      oProgress := ProgressBar():new( AppDeskTop(),, {400,350}, {AppDeskTop():currentsize()[1]-800,24},, .F. )
	      oProgress:create()
	      oProgress:color   := GRA_CLR_GREEN
	      oProgress:minimum := 1
	      oProgress:maximum := 20
			RunShell (' --headless --convert-to pdf:"writer_pdf_Export" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
				IF Len(Directory(cFilepdf)) > 0		// gibt es diese Datei schon mit frherem Zeitstempel von heute?:
					dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
					cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
					nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
					nZ := 0

                  oProgress:increment()      //+26.10.2023 18:59

					DO WHILE (nSZeit > nFZeit .OR. DATE() > dFDatum ) .AND. .NOT. nZ > 20
						sleep(100)
						dFDatum := Directory(cFilepdf)[1,F_WRITE_DATE]		//02.01.2023 13:03
						cFZeit := Directory(cFilepdf)[1,F_WRITE_TIME]
						nFZeit := Val(SubStr(cFZeit,1,2))*3600 + Val(SubStr(cFZeit,4,2))*60 + Val(SubStr(cFZeit,7,2))
						nZ++

                  oProgress:increment()      //+26.10.2023 18:59

					ENDDO
				ELSE		//05.10.2023 18:14 jetzt Schleife fr erste Datei des Tages
					nZ := 0
					DO WHILE Len(Directory(cFilepdf)) == 0 .AND. .NOT. nZ > 20
                  oProgress:increment()      //+27.11.2023 14:35
						sleep(50)
						nZ++
					ENDDO
				ENDIF
         oProgress:destroy()      //+26.10.2023 18:59
		ENDIF
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	   Runshell( [-compose "to=']+cMail_Adr+[',subject=']+cMail_Betr+[',body=']+cMail_Body+[',attachment=']+cFilePDF+['"], cMailClient, .T. ) //18.09.2020 09:39 von .F. auf .T., weil bei Sonnex Vorschau einfriert...
	ELSEIF !Upper(AppName())$"KSOX.EXE"		//02.01.2024 13:15
		RETURN .T.
	ENDIF

   IF !Empty(cNotiz_Bez)
      cVermerk := ConvToOEMCP(cNotiz_Bez) + ": "+DtoC(DATE()) + ", " + BriefAdresse(2,"A")	// 2==1-zeilig, "A"==Ansprechpartner
	   IF !cVermerk$1->notiz
	      1->(DbRlock())
	      1->notiz += CRLF + cVermerk
	      1->(DbCommit())
	   ENDIF
	ENDIF
RETURN .T.


//19.01.2023 12:39 aus der Knowledgebase -- wird hier aber tats„chlich NICHT gebraucht
// LongFilename2ShortFilename
FUNCTION Lfn2Sfn(cLfn)
LOCAL cSfn := space(len(clfn)+1)
LOCAL nsfn
    IF Set(_SET_CHARSET) == CHARSET_OEM
        cLfn := ConvToAnsiCp(cLfn)
    ENDIF
    nsfn := DllCall("Kernel32.dll",DLL_STDCALL, "GetShortPathNameA", ;
                     cLfn, @cSfn, len(cSfn)-1)
    cSfn := Left(cSfn, nsfn)
RETURN cSfn

//07.10.2022 18:00 Zeichenkette-Liste aus Inditext.txt in Array aLines bertragen
//						die Parameter cFile etc. in einer Array-Zeile ausw„hlen
//						die betreffende Textdatei cFile mit MemoRead einlesen
//						die Variablen mit VariFunkErsatz_1 im Text einsetzen
//						den Text ber HTML_Brief ausdrucken
FUNCTION Inditext_01(oDlg1,cFAV)		//12.09.2023 11:31 cFAV Fall/Adressen/Versicherung (identifiziert den Knopf F\ A\ V\)
	LOCAL cTexte := MemoRead(cDatver+cFAV+"Inditext.txt")
	LOCAL nMaxLines := MlCount(cTexte, 90)
	LOCAL aLines[nMaxLines], n
	LOCAL aParam := {}, nPosition
	LOCAL cFile, cFormular, cFont := '"Consolas", monospace', cFSize := '12pt', cFormSeite := '1cm 1cm 1cm 2cm', cZeileCM := '0.49cm'	// 28.10.2022 cZeileMM -> cZeileCM
	LOCAL cContainer := ""
	LOCAL cNotiz_Bez := ""
	LOCAL cMail_Adr := "Adresse von Hand eingeben"		//19.11.2023 11:43
	LOCAL cMail_Betr := ConvToAnsiCP("Formular fr Sterbefall")		//19.11.2023 11:43
	LOCAL nTxtnr := 0
	LOCAL CR := Chr(13), LF := Chr(10)
	LOCAL aPosition := {}	//02.01.2024 16:40
	PRIVATE cBuero := SubStr(cBU5,At(" ",cBU5)+1)	//11.10.2022 16:56 PRIVATE fr VariFunkErsatz_1
	PRIVATE cRufnummer := cBU6		//11.10.2022 16:56 PRIVATE fr VariFunkErsatz_1
	PRIVATE cHeute := DtoC(DATE())
	
	FOR n := 1 TO nMaxLines
		aLines[n] := Trim(MemoLine(cTexte, 200, n))
	NEXT

//	nTxtnr := ButtonFenster(aLines, oDlg1)	// in best4f.prg - zur Auswahl des Formulars in inditext.txt 
	nTxtnr := ListboxFenster(aLines, oDlg1, @cFormName, 0.9)	// 08.01.2024 11:53 zur Auswahl des Formulars in inditext.txt 
	IF Empty(nTxtnr)
		RETURN .F.
	ENDIF
	cText := aLines[nTxtnr]

	DO WHILE (nPosition := At("," , cText)) > 0
		AAdd(aParam, SubStr(cText, 1, nPosition-1))
		cText := SubStr(cText, nPosition+1)
	ENDDO
	IF Len(cText) > 0
		AAdd(aParam, cText)
	ENDIF
	
	cFile := cFAV+aParam[1]		//12.09.2023 12:31 cFAV - cFile f„ngt dann an mit z.B. "F\"
	IIf(Len(aParam) > 1,	cFormular := cFAV+aParam[2], )	//12.09.2023 12:31 cFAV - cFormular f„ngt dann an mit z.B. "F\"
	IIf(Len(aParam) > 2,	cFont := aParam[3], )
	IIf(Len(aParam) > 3,	cFSize := aParam[4], )
	IIf(Len(aParam) > 4,	cFormSeite := aParam[5], )
	IIf(Len(aParam) > 5,	cZeileCM := aParam[6], )
	IIf(Len(aParam) > 6,	cNotiz_Bez := aParam[7], )
	IIf(Len(aParam) > 7,	cMail_Adr := aParam[8], )		//19.11.2023 11:40
	IIf(Len(aParam) > 8,	cMail_Betr := aParam[9], )		//19.11.2023 11:40

	//21.11.2023 18:25 5->VERSKZ statt cMail_Adr in der inditext.txt: 
	IF  !"@"$cMail_Adr .AND. Len(cMail_Adr) < 6 
		IF 5->(DbSeek(cMail_Adr,.F.))
			cMail_Adr := 5->email
		ENDIF
	ENDIF

	IF AppKeyState(65554)==1	// zusammen mit ALT-Taste
	   ? RunShell (" /C START Notepad "+cDatver+cFAV+"inditext.txt",cComCom,.T.)	//12.09.2023 12:30 cFAV
	   ? RunShell (" /C START Notepad "+cDatver+cFile,cComCom,.T.)
	   cFileText := MemoRead(cDatver+cFile)
	   IF (")"+CR)$cFileText .OR. (")"+LF)$cFileText
	   	msgbox("Nach den Variablen unbedingt einen Leerschritt einbauen!")
	   ENDIF
	   RETURN .F.
	ENDIF

//30.10.2023 18:44 PDF-Formular in PNG umwandeln (nur einmalig beim ersten Mal)  vvvvvvvvvvvvvvvvvvvvvvv
	IF ".PDF"$Upper(cFormular) .AND. !"ORIGINAL.PDF"$Upper(cFormular)
		cFormularPNG := Stuff(cFormular,At(".PDF",Upper(cFormular)),4,".PNG")
		IF !FExists(cFormularPNG)
			cFormularPDF := cFormular
			xyz := RunShell (' --headless --convert-to png --outdir "F" &cFormularPDF', 'C:\Program Files\LibreOffice\program\sdraw.exe',.T.)
	//	  	xyz := RunShell (' --headless --convert-to png:"writer_png_Export:{\"PageRange\":{\"type\":\"string\",\"value\":\"2\"}}" --outdir "F" &cFormularPDF', 'C:\Program Files\LibreOffice\program\sdraw.exe',.T.)
			msgbox(cFormularPDF + " wird in eine PNG_Datei umgewandelt.")
			IF !FExists(cFormularPNG)
				msgbox("Umwandeln in PNG-Datei hat nicht geklappt!")
			ELSE
				cFormular := cFormularPNG
			ENDIF
		ELSE
			cFormular := cFormularPNG
		ENDIF
	ENDIF
//31.10.2023 09:22 DOC-Formular in PNG umwandeln (nur einmalig beim ersten Mal)  vvvvvvvvvvvvvvvvvvvvvvv
	IF ".DOC"$Upper(cFormular)
		cFormularPNG := Stuff(cFormular,At(".DOC",Upper(cFormular)),4,".PNG")
		IF !FExists(cFormularPNG)
			cFormularDOC := cFormular
			xyz := RunShell (' --headless --convert-to png --outdir "F" &cFormularDOC', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
			msgbox(cFormularDOC + " wird in eine PNG_Datei umgewandelt.")
			IF !FExists(cFormularPNG)
				msgbox("Umwandeln in PNG-Datei hat nicht geklappt!")
			ELSE
				cFormular := cFormularPNG
			ENDIF
		ELSE
			cFormular := cFormularPNG
		ENDIF
	ENDIF
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	IF Val(cZeileCM) == 0	// wenn kein Ausfll-Formular sondern ein freier Brief
		cFileInhalt := ConvToOEMCP(MemoRead(cDatver+cFile))	// wenn cFile nicht mit KSOX erzeugt wurde, dann kein ConvToOEMCP
//		cFile := MemoRead(cFile)	// wenn cFile nicht mit KSOX erzeugt wurde, dann kein ConvToOEMCP
		cContainer := VariFunkErsatz_1(cFileInhalt)	// in cFileInhalt steckt jetzt der komplette Text (nicht nur der Filename!)
	ELSE
		cFileInhalt := ConvToOEMCP(MemoRead(cDatver+cFile))	// den Formular-Text mit den eingebauten Variablen in cFile einlesen
		cFileInhalt := VariPosition_1(cFileInhalt,@cContainer, cFont, cFSize, cFormSeite, cZeileCM, cFile)	// in cFileInhalt steckt jetzt der komplette Text (nicht nur der Filename!)
	// in cContainer (== BriefText) werden von der Fkt. VariPosition_1() alle Variablen im Text positioniert bergeben.
	ENDIF
	IF AppKeyState(65552)==1	// zusammen mit Shift-Taste
		RETURN HTML_Brief_1(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez)
	ELSE
		RETURN HTML_Form_1(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez, "", cFile, cMail_Adr, cMail_Betr)	//19.11.2023 11:47
	ENDIF
RETURN .F.	//11.09.2023 16:48


//Die Ur-Funktion Inditext() ist in BlattDrG.prg bei KSOX
//23.01.2024 15:31 InditextF.txt heiát die neue Inditext-Datei, die in M:\HDBE\F\ liegt
//07.10.2022 18:00 Zeichenkette-Liste aus InditextF.txt in Array aLines bertragen
//						die Parameter cFile etc. in einer Array-Zeile ausw„hlen
//						die betreffende Textdatei cFile mit MemoRead einlesen
//						die Variablen mit VariFunkErsatz_1 im Text einsetzen
//						den Text ber HTML_Brief_2 ausdrucken
FUNCTION Inditext_1(oDlg1,cFAV)		//12.09.2023 11:31 cFAV Fall/Adressen/Versicherung (identifiziert den Knopf F\ A\ V\)
	LOCAL cTexte := MemoRead(cDatver+cFAV+"Inditext"+cFAV[1]+IIf("Formulare"$cFAV,"F.txt",".txt"))
	LOCAL nMaxLinesTxt := MlCount(cTexte, 90)
	LOCAL aLines[nMaxLinesTxt], n
	LOCAL aParam := {}, nPosition
	LOCAL cFile, cFormular, cFont := '"Consolas", monospace', cFSize := '12pt', cFormSeite := '1cm 1cm 1cm 2cm', cZeileCM := '0.49cm'	// 28.10.2022 cZeileMM -> cZeileCM
	LOCAL cContainer := ""
	LOCAL cNotiz_Bez := ""
	LOCAL cMail_Adr := "Adresse von Hand eingeben"		//19.11.2023 11:43
	LOCAL cMail_Betr := ConvToAnsiCP("Formular fr Sterbefall")		//19.11.2023 11:43
	LOCAL nTxtnr := 0
	LOCAL CR := Chr(13), LF := Chr(10)
	LOCAL aPosition := {}	//02.01.2024 16:40
	LOCAL cText, cFileText, cFileInhalt, nAnf, nEnd	//19.02.2024 16:13 nachtr„glich als LOCAL erkl„rt
	LOCAL cPosition, cFileInh	//19.02.2024 16:12 nachtr„glich
	//05.01.2024 15:33 der Link zum PDF-Programm ist in der Datei PdfProgLinks vvvvvvvvvv
	LOCAL cTextPP := IIf(FExists(cDatver+"PdfProgLinks.txt"),MemoRead(cDatver+"PdfProgLinks.txt"),"")
	LOCAL nMaxLines := MlCount(cTextPP, 90)
	LOCAL aPPLinks[nMaxLines]		//doppelt  , n
	PRIVATE cPPLinks := cTextPP
	PRIVATE cBuero := SubStr(cBU5,At(" ",cBU5)+1)	//11.10.2022 16:56 PRIVATE fr VariFunkErsatz_1
	PRIVATE cRufnummer := cBU6		//11.10.2022 16:56 PRIVATE fr VariFunkErsatz_1
	PRIVATE cHeute := DtoC(DATE())
	PRIVATE cAusfuell := "PDF"		//18.02.2024 10:27 "PDF"/"HTML"
	PRIVATE cVariable	//19.02.2024 16:09 nachtr„glich als PRIVATE erkl„rt
	PRIVATE cFormularPNG, cFormularJPG, cFormularDOC, cFormularPDF 
	PRIVATE cFAVp := cFAV[1]	//27.02.2024 11:07
	PRIVATE cMA		//05.03.2024 14:13	wegen Makro bei cMail_Adr
		
/*	// nur fr KSOX gedacht:
	IF "KSOX"$Upper(Appname())
	   DO CASE
	      CASE cSystem == "14" .OR. "Dortmund"$(za05x+za05)
	         cBuero := "Dortmund"
	         cRufnummer := "0231 1857 797"
	      CASE cSystem == "18" .OR. "Duisburg"$(za05x+za05)
	         cBuero := "Duisburg"
	         cRufnummer := "0203 404140"
	      CASE cSystem == "19" .OR. "Essen"$(za05x+za05)
	         cBuero := "Essen"
	         cRufnummer := "0201 766070"
	      CASE cSystem == "17" .OR. "Gelsenkirchen"$(za05x+za05)
	         cBuero := "Gelsenkirchen"
	         cRufnummer := "0209 9442888"
	      CASE cSystem == "15" .OR. "Herne"$(za05x+za05)
	         cBuero := "Herne"
	         cRufnummer := "02323 1460600"
	      CASE cSystem == "16" .OR. "Oberhausen"$(za05x+za05)
	         cBuero := "Oberhausen"
	         cRufnummer := "0208 631349"
	   ENDCASE
	ENDIF
*/
	cTexte := Stuff(cTexte,At("SCANS\DOKUMENTE",Upper(cTexte))+15,0,"\"+StrZero(1->auftrnr,6,0))	//24.04.2025 10:18
	
	FOR n := 1 TO nMaxLinesTxt
		aLines[n] := Trim(MemoLine(cTexte, 200, n))
	NEXT

	nTxtnr := ListboxFenster(aLines, oDlg1, @cFormName, 0.9)	// in best4f.prg - zur Auswahl des Formulars in inditextF.txt 
	IF Empty(nTxtnr)
		RETURN .F.
	ENDIF
	cText := aLines[nTxtnr]
	IF Len(cText) == 0
		RETURN .F.
	ENDIF
	IF !","$aLines[nTxtnr]	//16.04.2025 09:36 .AND. Len(aParam) <= 5 .AND. !"ORIGINAL.PDF"$Upper(aParam[2])	//13.04.2025 15:02
		msgbox("keine gltige Parameterdatei ausgew„hlt!")
		RETURN .F.
	ENDIF

	DO WHILE (nPosition := At("," , cText)) > 0
//05.04.2025 18:36		AAdd(aParam, SubStr(cText, 1, nPosition-1))
		AAdd(aParam, AllTrim(SubStr(cText, 1, nPosition-1)))	//05.04.2025 18:37
		cText := SubStr(cText, nPosition+1)
	ENDDO
	IF Len(cText) > 0
//05.04.2025 18:37		AAdd(aParam, cText)
		AAdd(aParam, AllTrim(cText))		//05.04.2025 18:37
	ENDIF
	
			//24.04.2025 10:34 im Archiv dieses Sterbefalls eine Datei aussuchen und anzeigen:
			IF "SCANS\DOKUMENTE"$Upper(aParam[2])
				cFileX := GetFilename(aParam[2])
				IF !Empty(cFileX) .AND. ".PDF"$Upper(cFileX)
					//05.01.2024 cPPLinks aus: FExists(cDatver+"PdfProgLinks.txt")
					// speziell fr BleinX, weil ein PC keinen AdobeReader kann
					IF Len(cPPLinks)>0	
						FOR n := 1 TO nMaxLines
							aPPLinks[n] := Trim(MemoLine(cPPLinks, 100, n))
						NEXT
						FOR n := 1 TO Len(aPPLinks)
							cPPLinks := aPPLinks[n]	// cPPLinks wird hier doppelt verwendet ...
							IF FExists(cPPLinks)
								RunShell ("&cFilepdf",cPPLinks,.T.)
								EXIT
							ENDIF
						NEXT
						IIf(n>len(aPPLinks), msgbox("Das PDF-Programm ist nicht ordentlich installiert!"),)
					ELSE
						IF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe')							//64bit Reader
							RunShell ("&cFilepdf","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.)
						ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe')		//32bit Reader
							RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.)
						ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe')			// Test nur fr BleinX
							RunShell ("&cFilepdf","C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe",.T.)
						ELSE
							msgbox("Der Adobe Reader DC ist nicht ordentlich installiert!")
						ENDIF
					ENDIF
				ELSEIF !Empty(cFileX)
					RunShell ("&cFileX","C:\Program Files\LibreOffice\program\soffice.exe",.T.)
				ENDIF
				RETURN .T.	// es war ja nur die Suche und Anzeige der Datei gewnscht
			ENDIF

	cFile := cFAV+aParam[1]		//12.09.2023 12:31 cFAV - cFile f„ngt dann an mit z.B. "F\"
	IIf(Len(aParam) > 1,	cFormular := cFAV+aParam[2], )	//12.09.2023 12:31 cFAV - cFormular f„ngt dann an mit z.B. "F\"
	IIf(Len(aParam) > 2,	cFont := aParam[3], )
	IIf(Len(aParam) > 3,	cFSize := aParam[4], )
	IIf(Len(aParam) > 4,	cFormSeite := aParam[5], )
	IIf(Len(aParam) > 5,	cZeileCM := aParam[6], )
	IIf(Len(aParam) > 6,	cNotiz_Bez := aParam[7], )
	IIf(Len(aParam) > 7,	cMail_Adr := aParam[8], )		//19.11.2023 11:40
	IIf(Len(aParam) > 8,	cMail_Betr := aParam[9], )		//19.11.2023 11:40

	// wenn cMail_Adr = "Email" oder "Notiz", dann im Fall suchen:
	cMail_Adr := Lower(AllTrim(cMail_Adr))
	IF cMail_Adr$"email e-mail notiz notizfeld"
		// die Mail-Adresse in der Hauptmaske auf dem Platz Konto-Inhaber:
		IF cMail_Adr$"email e-mail"
			cMail_Adr := AllTrim(1->ansp_ktoi)
		ENDIF
		// die Mail-Adresse im Notizfeld der Hauptmaske (in eigener Zeile):
		// Email: irgendwer@irgendwas.xy
		IF cMail_Adr$"notiz notizfeld"
			cNotiz := Lower(1->notiz)
			IF "email:"$cNotiz
				nAnf := At("email:",cNotiz)+6
				nEnd := At(Chr(13),cNotiz,nAnf)-1
				nEnd := IIf(nEnd==0,Len(cNotiz),nEnd)
				cMail_Adr := AllTrim(SubStr(1->notiz,nAnf,nEnd-nAnf+1))
			ELSEIF "e-mail:"$cNotiz
				nAnf := At("e-mail:",cNotiz)+7
				nEnd := At(Chr(13),cNotiz,nAnf)-1
				nEnd := IIf(nEnd==0,Len(cNotiz),nEnd)
				cMail_Adr := AllTrim(SubStr(1->notiz,nAnf,nEnd-nAnf+1))
			ELSE
				cMail_Adr := ""
			ENDIF
		ENDIF
	//21.11.2023 18:25 wenn 5->VERSKZ statt cMail_Adr in der inditextF.txt steht: 
	ELSEIF  !"@"$cMail_Adr .AND. Len(cMail_Adr) < 6 
		IF 5->(DbSeek(cMail_Adr,.F.))
			cMail_Adr := 5->email
		ENDIF
	ELSEIF 1->(IsFieldVar(cMail_Adr))		//05.03.2024 14:11 z.B.: ansp_email
		cMA := cMail_Adr	// wegen Makro in n„chster Zeile:
		cMail_Adr := 1->&cMA
	ENDIF

	// die gew„hlte .txt-Datei + inditextX.txt in Notepad laden und zeigen:
	IF AppKeyState(65554)==1 .AND. !"ORIGINAL.PDF"$Upper(cFormular)	// zusammen mit ALT-Taste	//24.04.2025 10:18 ORIGINAL
	   ? RunShell (" /C START Notepad "+cDatver+cFAV+"inditext"+cFAV[1]+".txt",cComCom,.T.)	//12.09.2023 12:30 cFAV
		IF SubStr(Upper(cFile),Len(cFile)-3) == ".TXT"
		   ? RunShell (" /C START Notepad "+cDatver+cFile,cComCom,.T.)
		   cFileText := MemoRead(cDatver+cFile)
		   IF (")"+CR)$cFileText .OR. (")"+LF)$cFileText
		   	msgbox("Nach den Variablen unbedingt einen Leerschritt einbauen!")
		   ENDIF
		ELSE
			RunShell ( cFile,"c:\Program Files\LibreOffice\program\swriter.exe")
		ENDIF
	   RETURN .F.
	ELSEIF AppKeyState(65553)==1 .AND. !"ORIGINAL.PDF"$Upper(cFormular)		// zusammen mit STRG-Taste	//24.04.2025 10:18 ORIGINAL
		cContainer := ""	// Inhalt = leer, nur das Formular drucken
		RETURN HTML_Form_1(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez, "", cFile, cMail_Adr, cMail_Betr)	//05.05.2024 15:09
	ELSEIF "ORIGINAL.PDF"$Upper(cFormular)	// 10.04.2025 11:14: ausfllbares Original-PDF
		cFile := FormSuche(cDatver+cFile,"*.pdf")	 
		IF ValType(cFile)!="C" .OR. Len(cFile)<5		//14.04.2025 15:17
			RETURN .F.
		ENDIF
		cContainer := ""	// Inhalt = leer, nur das Formular drucken
		RETURN HTML_Form_1(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez, "", cFile, cMail_Adr, cMail_Betr)	//05.05.2024 15:09
	ELSEIF !FExists(cDatver+cFormular) .OR. AppKeyState(65552)==1	// zusammen mit SHIFT-Taste 02.01.2024 12:04
		cFormular := ""				// Daten ohne Hintergrund ausdrucken (z.B. ohne Briefbogen)
	ENDIF

		//26.02.2024 11:51 erstellt die FEx_*-Datei aus der aktuellen KSOX-Daten-Datei: vvvvvvvvvvvvvvvvv
		IF SubStr(Upper(cFile),Len(cFile)-3) == ".ODT"
			IF !FExport()
				msgbox("Daten-Export hat nicht geklappt!")
			ENDIF
			RETURN ODT_Form_1("", "", "", "", "", "", cNotiz_Bez," ", cFile)	//26.02.2024 19:05
		ENDIF
		//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
		
//23.01.2024 15:54 JPG-Formular in PNG umwandeln (nur einmalig beim ersten Mal)  vvvvvvvvvvvvvvvvvvvvvvv
	IF ".JPG"$Upper(cFormular) .AND. !"ORIGINAL.JPG"$Upper(cFormular)
		cFormularPNG := Stuff(cFormular,At(".JPG",Upper(cFormular)),4,".PNG")
		IF !FExists(cDatver+cFormularPNG)
			cFormularJPG := cFormular
			cParam := cDatver + cFormularJPG + ' /convert=' + Substr(cFormularPNG,3)
//			xyz := RunShell (' --headless --convert-to png --outdir &cFAVp &cFormularJPG', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
			xyz := RunShell (' &cParam', 'C:\Program Files\IrfanView\i_view64.exe',.T.)
			msgbox(cFormularJPG + " wird in eine PNG_Datei umgewandelt.")
			IF !FExists(cDatver+cFormularPNG)
				msgbox("Umwandeln in PNG-Datei hat nicht geklappt!")
			ELSE
				cFormular := cFormularPNG
			ENDIF
		ELSE
			cFormular := cFormularPNG
		ENDIF
	ENDIF
//30.10.2023 18:44 PDF-Formular in PNG umwandeln (nur einmalig beim ersten Mal)  vvvvvvvvvvvvvvvvvvvvvvv
	IF ".PDF"$Upper(cFormular) .AND. !"ORIGINAL.PDF"$Upper(cFormular)
		cFormularPNG := Stuff(cFormular,At(".PDF",Upper(cFormular)),4,".PNG")
		IF !FExists(cDatver+cFormularPNG)
			cFormularPDF := cFormular
//			xyz := RunShell (' --headless --convert-to "png:writer_png_Export" --outdir &cFAVp &cFormularPDF', 'C:\Program Files\LibreOffice\program\sdraw.exe',.T.)
//		  	xyz := RunShell (' --headless --convert-to "png:writer_png_Export:{\"PageRange\":{\"type\":\"string\",\"value\":\"1\"}}" --outdir "F" &cFormularPDF', 'C:\Program Files\LibreOffice\program\sdraw.exe',.T.)
			cParam := cDatver + cFormularPDF + ' /convert=' + Substr(cFormularPNG,3)
			xyz := RunShell (' &cParam', 'C:\Program Files\IrfanView\i_view64.exe',.T.)
			msgbox(cFormularPDF + " wird in eine PNG_Datei umgewandelt.")
			IF !FExists(cDatver+cFormularPNG)
				msgbox("Umwandeln in PNG-Datei hat nicht geklappt!")
			ELSE
				cFormular := cFormularPNG
			ENDIF
		ELSE
			cFormular := cFormularPNG
		ENDIF
	ENDIF
//23.01.2024 14:42 ODT erg„nzt
//31.10.2023 09:22 DOC-Formular in PNG umwandeln (nur einmalig beim ersten Mal)  vvvvvvvvvvvvvvvvvvvvvvv
	IF ".DOC"$Upper(cFormular) .OR. ".ODT"$Upper(cFormular)
		cFormularPNG := Stuff(cFormular,At(IIf(".DOC"$Upper(cFormular),".DOC",".ODT"),Upper(cFormular)),4,".PNG")
		IF !FExists(cDatver+cFormularPNG)
			cFormularDOC := cFormular
			xyz := RunShell (' --headless --convert-to png --outdir &cFAVp &cFormularDOC', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
			msgbox(cFormularDOC + " wird in eine PNG_Datei umgewandelt.")
			IF !FExists(cDatver+cFormularPNG)
				msgbox("Umwandeln in PNG-Datei hat nicht geklappt!")
			ELSE
				cFormular := cFormularPNG
			ENDIF
		ELSE
			cFormular := cFormularPNG
		ENDIF
	ENDIF
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	cFileInhalt := ConvToOEMCP(MemoRead(cDatver+cFile))	// den Formular-Text mit den eingebauten Variablen in cFile einlesen
   cVariable := SubStr( cFileInhalt, At("$",cFileInhalt)+1, At(") ",cFileInhalt,At("$",cFileInhalt))-At("$",cFileInhalt) )
		//02.01.2024 16:35 damit 'alte' KSOX-Formulare noch im flieáenden Text positioniert werden,
		//							wird hier aPosition geholt, um dessen Len() abzufragen
      IF ","$cVariable .AND. Len(cVariable)>5
			nAnf := At(",",cVariable)+1
			nEnd := Len(cVariable)
			WHILE nEnd-nAnf > 12
				nAnf := At(",",cVariable,nAnf)+1
			ENDDO
			cPosition := SubStr(cVariable,nAnf,nEnd-nAnf)

			// berechnet die absolute Lage der Variablen auf der Seite:   vvvvvvvvvvvvvvvvvvvvvvvvvvv
			// wie bei php: aPosition = explode(cPosition)
			DO WHILE (nPosition := At("," , cPosition)) > 0
				AAdd(aPosition, Val(SubStr(cPosition, 1, nPosition-1)))
				cPosition := SubStr(cPosition, nPosition+1)
			ENDDO
			IF Len(cPosition) > 0
				AAdd(aPosition, Val(cPosition) - Val(cZeileCM) * 100)	// -nZeileMM, weil die Einstellung.txt die Werte vom Unterstrich hat... 
			ENDIF																//				...w„hrend ein SPAN seine Positionswerte oben links hat
      	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

			cVariable := SubStr(cVariable,2,nAnf-3)
		ENDIF

	IF "KSOX"$Upper(AppName()) .AND. Len(aPosition) < 3 //.AND. Val(cZeileCM) > 0
	// 02.01.2024 16:35 damit 'alte' KSOX-Formulare noch im flieáenden Text positioniert werden
		IF cVariable == "''"	// 17.02.2024 15:49	$('',1,1) als erste Zeile
			cAusfuell := "HTML"	//18.02.2024 10:28 ausfllen als .html mit LO
			cFileInh := VariPosition_1(cFileInhalt,@cContainer, cFont, cFSize, cFormSeite, cZeileCM, cFile)	// in cFileInhalt steckt jetzt der komplette Text (nicht nur der Filename!)
		ELSEIF Val(cZeileCM) == 0
			cContainer := VariErsatz(cFileInhalt)		//d.h.: alte KSOX-Funktion in BlattDrG
		ELSE
			cFileInh := VariPosition(cFileInhalt,@cContainer, cFont, cFSize, cFormSeite, cZeileCM)	// in cFile steckt jetzt der komplette Text (nicht nur der Filename!)
		// in cContainer (== BriefText) werden von der Fkt. VariPosition() alle Variablen im Text positioniert bergeben.
		ENDIF
	//zum Test	MemoWrit("XXcFile.txt",cFile)
	//zum Test	MemoWrit("XXcCont.txt",cContainer)
		RETURN HTML_Form_1(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez,"", cFile, cMail_Adr, cMail_Betr)	//05.05.2024 15:09
	ELSE // wenn Len(aPosition)>=3 auch fr KSOX!
	// fr alle Bestatter	
		IF Val(cZeileCM) == 0
			cContainer := VariFunkErsatz_1(cFileInhalt)	// in cFileInhalt steckt jetzt der komplette Text (nicht nur der Filename!)
		ELSE
			cAusfuell := IIf(cVariable=="''","HTML","PDF")		//05.03.2024 15:13
			cFileInhalt := VariPosition_1(cFileInhalt,@cContainer, cFont, cFSize, cFormSeite, cZeileCM, cFile)	// in cFileInhalt steckt jetzt der komplette Text (nicht nur der Filename!)
		// in cContainer (== BriefText) werden von der Fkt. VariPosition_1() alle Variablen im Text positioniert bergeben.
		ENDIF
		IF Val(cZeileCM) == 0	// 'altes' Briefformat (ohne input-Felder)
			RETURN HTML_Brief_1(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez)
		ELSE
			RETURN HTML_Form_1(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez, "", cFile, cMail_Adr, cMail_Betr)	//19.11.2023 11:47
		ENDIF
	ENDIF
RETURN .F.	//11.09.2023 16:48

//10.04.2025 19:14 wird zun„chst nur von ineux aufgerufen, wenn f gedrckt wird
// Die Namen der Formulardateien in cDir werden 'aufbereitet', ohne Space/Komma/Klammer/Umlaute
FUNCTION FormBereitung(cDir)
	LOCAL ADir := Directory( cDir + "\", "D" )
   LOCAL imax := Len( aDir )
   LOCAL i, cFile, cFileraw, j
	LOCAL cUml1 := "„”᎙š"
	LOCAL cUml2 := "aeoeuessAEOEUE"
	LOCAL aDirName := Array(0)
	
   FOR i:=1 TO imax		// jeden Dir-Eintrag einzeln 
      IF "D" $ aDir[i,F_ATTR]        .AND. ;
         .NOT. aDir[i,F_NAME] == "." .AND. ;
         .NOT. aDir[i,F_NAME] == ".."				// nur Dir, aber nicht ./.. (und keine Files!)
   		cFileraw := ConvToOEMCP(aDir[i,F_NAME])
		   cFile := cFileraw
			DO WHILE " "$cFile							// Leerzeichen durch '_' ersetzen
				cFile := Stuff(cFile,At(" ",cFile),1,"_")
			ENDDO
			DO WHILE ","$cFile							// Komma durch Punkt ersetzen
				cFile := Stuff(cFile,At(",",cFile),1,".")
			ENDDO
			DO WHILE "("$cFile							// 'Klammer auf' durch '-' ersetzen
				cFile := Stuff(cFile,At("(",cFile),1,"-")
			ENDDO
			DO WHILE ")"$cFile							// 'Klammer zu' durch '-' ersetzen
				cFile := Stuff(cFile,At(")",cFile),1,"-")
			ENDDO
   
			FOR j:=1 TO 7									// Umlaute durch 'ae' ersetzen
				DO WHILE cUml1[j]$cFile
					cFile := Stuff(cFile,At(cUml1[j],cFile),1,cUml2[2*j-1]+cUml2[2*j])
				ENDDO
			NEXT

			IF cFile != cFileraw							// wenn es Unterschiede gibt:
				FRename(cDir+"\"+ConvToAnsiCP(cFileraw),cDir+"\"+cFile)					// alten Namen durch neuen ersetzen
			ENDIF
	   	AAdd(aDirName,cDir+"\"+cFile)
   	ENDIF
   NEXT
RETURN aDirName

//08.04.2025 18:25 zum Ausw„hlen von Original-Ausfllbaren-PDFs:
FUNCTION FormSuche(cDir,cDatei)
	LOCAL oDlg, cFileraw, cFile := ""	// damit nicht NIL als Filename entsteht
	LOCAL cCD := CurDir(cDir)	// bisheriges CurDir gesichert und neues eingestellt
	LOCAL cUml1 := "„”᎙š"
	LOCAL cUml2 := "aeoeuessAEOEUE"
	LOCAL j
	      oDlg := XbpFileDialog():new()
	      oDlg:title := "W„hlen Sie ein Formular aus:"
	      oDlg:CREATE(AppDeskTop())
	      cFileraw := oDlg:open(cDir+"\"+cDatei)
	      oDlg:destroy()
	      // *raw-Dateien werden auf Leerzeichen " " und Umlaute untersucht und korrigiert mit "_" ... ae-oe-ue-ss...
	      IF !Empty(cFileraw)
			   cFile := cFileraw
				DO WHILE " "$cFile							// Leerzeichen durch '_' ersetzen
					cFile := Stuff(cFile,At(" ",cFile),1,"_")
				ENDDO
				DO WHILE ","$cFile							// Komma durch Punkt ersetzen
					cFile := Stuff(cFile,At(",",cFile),1,".")
				ENDDO
				DO WHILE "("$cFile							// 'Klammer auf' durch '-' ersetzen
					cFile := Stuff(cFile,At("(",cFile),1,"-")
				ENDDO
				DO WHILE ")"$cFile							// 'Klammer zu' durch '-' ersetzen
					cFile := Stuff(cFile,At(")",cFile),1,"-")
				ENDDO
	   
				FOR j:=1 TO 7									// Umlaute durch 'ae' ersetzen
					DO WHILE cUml1[j]$cFile
						cFile := Stuff(cFile,At(cUml1[j],cFile),1,cUml2[2*j-1]+cUml2[2*j])
					ENDDO
				NEXT
	
				IF cFile != cFileraw							// wenn es Unterschiede gibt:
//13.04.2025 21:14					FRename(cDir+"\"+ConvToAnsiCP(cFileraw),cDir+"\"+cFile)					// alten Namen durch neuen ersetzen
					FRename(ConvToAnsiCP(cFileraw),cFile)					// alten Namen durch neuen ersetzen
				ENDIF
			ENDIF
			CurDir("C:\"+cCD)		// altes CurDir wieder hergestellt
RETURN cFile	//13.04.2025 20:39
//13.04.2025 20:39 HTML_Form_2("", "Original.pdf", "", "", "", "", "", "", cFile, "", "")

******************************************************************
* Dateinamen mit Filedialog abfragen (08.04.2025 17:33: BEISPIEL)
******************************************************************
//FUNCTION GetFilename()
//   LOCAL oDlg := XbpFiledialog():New(), cFile
//
//   oDlg:Title := "Please select DBF file"
//   oDlg:Create()
//   cFile := oDlg:Open( "..\..\DATA\*.DBF" )
//
//RETURN cFile
FUNCTION GetFilename(cDir,cStartDir,cTitle)
   LOCAL oDlg := XbpFiledialog():New(), cFile
	DEFAULT cStartDir TO cDatver
	DEFAULT cTitel TO "W„hlen Sie eine Datei"

   oDlg:Title := cTitle
   oDlg:Create()
   cFile := oDlg:Open( cStartDir+cDir )

RETURN cFile


/*03.07.2008 17:18 zum Ersetzen von Variablenbezeichnungen in einem Text durch den Variablenwert
      Die Bezeichnung muss von einem $ angefhrt werden und mit einem Space enden: z.B. $1->auftrnr ...
      Vielleicht kann man auch Funktionen einbauen, indem man sie in Klammern setzt?: auch ohne!!*/
   /* Variablen-Namen: entweder Feldvariablen der aktuellen WorkArea, z.B. $(
                       oder bei "N" mit LenDec am Ende, z.B. 62 
                       "N"-Variable mssen im Text in Klammern stehen: $(nRate62) */
  /*12.10.2022 14:11 IMMER die Variablen in Klammern() setzen, denn 'FieldInfo(FieldPos(SubStr' verl„sst sich darauf.*/
// umbenannt in VariFunkErsatz_1, weil ohne Funk es bereits in AAA existierte
//14.02.2026 17:44 abgeglichen mit VariFunkErsatz_2 !!!!!!!!
FUNCTION VariFunkErsatz_1( cString)
   LOCAL nVarLen, nTabLen := 0
   PRIVATE cVariable 
   DO WHILE At("$",cString) > 0
      /* der Variablen-Name:*/
      IF At("$",cString) == At("$('", cString)	/*literal String in '' */
	      cVariable := SubStr( cString, At("$",cString)+1, At("') ",cString,At("$",cString))-At("$",cString)+1 )
	      /* die L„nge des Namens der Variablen: */
	      nVarLen := At(") ",cString,At("$(",cString))-At("$(",cString)+1
      ELSE
      	//09.12.2023 21:04	vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
	      cVariable := SubStr( cString, At("$",cString)+1, At(") ",cString,At("$",cString))-At("$",cString) )
			nVarLen := Len(cVariable)		// fr Ersetzung in der Variablen cString s.u.
			//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
			IF At("),",cString) > 0 .AND. At(") ",cString) > At("),",cString)
		      cVariable := SubStr( cString, At("$",cString)+1, At("),",cString,At("$",cString))-At("$",cString) )
		      /* die L„nge des Namens der Variablen: */
		      nVarLen := At(", ",cString,At("$",cString))-At("$",cString)
//09.12.2023 20:54 aus VariPosition_1 wegen CodeBlock etc... vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
			ELSEIF Len(cVariable)>=5 .AND. (","$cVariable .OR. "{||"$cVariable .OR. "->"$cVariable .OR. ":"$cVariable)
				IF (At("{||",cVariable)>0 .AND. At("})",cVariable)>0)		//29.08.2023 19:10 wenn ein CodeBlock drin ist ohne Position
					cPosition := "0,0"
					cVariable := SubStr(cVariable,2,Len(cVariable)-2)
				ELSEIF !","$cVariable .OR. (At("{||",cVariable)>0 .AND. At("}",cVariable) > RAt(",",cVariable))	// wenn komma nur im Codeblock
					cPosition := "0,0"																									// -> keine Position
					cVariable := SubStr(cVariable,2,Len(cVariable)-2)
				ELSEIF "')"$cVariable .AND. At(")",cVariable) > RAt(",",cvariable)			// literal String ohne Position
					cPosition := "0,0"																		// -> keine Position
					cVariable := SubStr(cVariable,2,Len(cVariable)-2)
				ELSEIF "))"$cVariable .AND. At("))",cVariable) == Len(cVariable)-1			// Function ohne Position
					cPosition := "0,0"																		// -> keine Position
					cVariable := SubStr(cVariable,2,Len(cVariable)-2)
				ELSE
					IF At("{||",cVariable)>0 .AND. At("}",cVariable) < RAt(",",cVariable)			// Komma auch hinter dem Codeblock
						nAnf := At(",",cVariable,At("}",cVariable))+1		//Codeblock
					ELSEIF (nAnf := RAt(')',cVariable,Len(cVariable)-1)) > 0			//cVariable = Function
						nAnf += 2
					ELSE
						nAnf := At(",",cVariable)+1								//Variable
					ENDIF 
					nEnd := Len(cVariable)
					cPosition := SubStr(cVariable,nAnf,nEnd-nAnf)
					cVariable := SubStr(cVariable,2,nAnf-3)				// isoliert die Variable/den CodeBlock
				ENDIF
				//29.08.2023 20:59 fhrt den CodeBlock aus und macht daraus eine literale String mit Hilfe Chr(39)
				IF "{||"$cVariable
					xVariable := Eval(&cVariable)	// 29.08.2023 19:19 den CodeBlock ausfhren
					IF ValType(xVariable) == "C"
						cVariable := Chr(39)+xVariable+Chr(39)
					ELSEIF ValType(xVariable) == "N"
						cVariable := Chr(39)+AllTrim(Str(xVariable))+Chr(39)
					ELSEIF ValType(xVariable) == "D"
						cVariable := Chr(39)+DtoC(xVariable)+Chr(39)
					ENDIF
				ENDIF
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
		      nVarLen := At(" ",cString,At("$",cString))-At("$",cString)	//10.12.2023 15:38 testweise

		   ELSE	// bleibt noch wie im VariFunkErsatz-Original (09.12.2023 21:01)
		      cVariable := SubStr( cString, At("$",cString)+1, At(") ",cString,At("$",cString))-At("$",cString) )
		      /* die L„nge des Namens der Variablen: */
		      nVarLen := At(" ",cString,At("$",cString))-At("$",cString)
			ENDIF
	   ENDIF

	   IF TYPE(cVariable)$"UE"
	   	msgbox("Fehler bei der Variablen:"+cVariable)
	   	cString := Stuff(cString,At("$",cString),nVarLen,"X X X X X")
	   	LOOP
	   ENDIF

   	cVariable = IIf("IIF"==SubStr(Upper(cVariable),0,3),&cVariable,cVariable)	//28.08.2023 09:41 Testweise
   	aF_Info := IIf(ValType(&cVariable)=="N" .AND. "->"$cVariable, F_Info(cVariable), {,})	//28.03.2023 19:06 FieldInfo()

      /* wenn nach der Variablen mehr als ein Space, dann PadR, damit Tab-Abst„nde erhalten bleiben: */
      cString := Stuff(cString,At("$",cString),nVarLen, ;
                           IIf(At(" ",cString,At("$",cString))!=At(" "+Chr(9),cString,At("$",cString)), ;
                               ; /* wenn also der Abstand nur ein Space ist ... */
                                 IIf(ValType(&cVariable)$"CM", ;
                                     ; /* ... dann StringVariable mit AllTrim komprimieren: */
                                       AllTrim(&cVariable), ;
                                     ; /* NumVariable in Strings verwandeln: */
                                       IIf(ValType(&cVariable)=="N", ;
                                           ; /* Mem- oder Feldvariable? */
                                             IIf("->"$cVariable, ;
                                                 ; /* Feldvariable: Dezimalstellen aus FieldInfo holen: */
                                                   Str(&cVariable, ;		/*12.10.2022 13:59  nVarLen-6 als nCount fr Substr(cVariable)  4mal in VariFunkErsatz_1() */
					                                      aF_Info[1], ;	/* FieldInfo(FieldPos(SubStr(cVariable,At(">",cVariable)+1,nVarLen-6)),FLD_LEN), ; */
               					                       aF_Info[2]  ;   /* FieldInfo(FieldPos(SubStr(cVariable,At(">",cVariable)+1,nVarLen-6)),FLD_DEC) ; */
                                                      ), ;
                                                 ; /* Memvariable: Dezimalstellen aus 2stelliger Zahl holen: */
                                                   Str(&cVariable, ;
                                                                  Val(cVariable[At(")",cVariable)-2]), ;
                                                                  Val(cVariable[At(")",cVariable)-1]) ;
                                                      ) ;
                                                ), ;
                                           ; /* Datumsvariable in String verwandeln */
                                             IIf(ValType(&cVariable)=="D", ;
                                                   DtoC(&cVariable), ;
                                                   IIf( Upper(cVariable[1])$"D", ;
                                                         DtoC( DATE() + Val(SubStr(cVariable,2))), ;
                                                         "" ;
                                                      ) ;
                                                ) ;
                                          ) ;
                                    ), ;
                               ; /* wenn aber der Abstand mehr als ein Space ist (=TAB) */
                                 IIf(ValType(&cVariable)$"CM", ;
                               ; /* damit die Variable nach der Umwandlung denselben Platz einnimmt: */
                                       PadR(AllTrim(&cVariable), nVarLen ), ;
                                     ; /* NumVariable in Strings verwandeln: */
                                       IIf(ValType(&cVariable)=="N", ;
                                           ; /* Mem- oder Feldvariable? */
                                             IIf("->"$cVariable, ;
                                                 ; /* Feldvariable: Dezimalstellen aus FieldInfo holen: */
                                                   Str(&cVariable, ;
					                                      aF_Info[1], ;	/* FieldInfo(FieldPos(SubStr(cVariable,At(">",cVariable)+1,nVarLen-6)),FLD_LEN), ; */
               					                       aF_Info[2]  ;   /* FieldInfo(FieldPos(SubStr(cVariable,At(">",cVariable)+1,nVarLen-6)),FLD_DEC) ; */
                                                      ), ;
                                                 ; /* Memvariable: Dezimalstellen aus 2stelliger Zahl holen: */
                                                   Str(&cVariable, ;
                                                                  Val(cVariable[At(")",cVariable)-2]), ;
                                                                  Val(cVariable[At(")",cVariable)-1]) ;
                                                      ) ;
                                                ), ;
                                           ; /* Datumsvariable in String verwandeln */
                                             IIf(ValType(&cVariable)=="D", ;
                                                   PadR(DtoC(&cVariable), nVarLen ), ;
                                                   "" ;
                                                ) ;
                                          ) ;
                                    ) ;
                              ) ;
                      )
       /* & = Makro-Operator: wegen 'Wert der Variablen' */
   ENDDO
RETURN cString


// 13.10.2022 11:06 entwickelt aus VariFunkErsatz(): (muss noch durch die ganze IIf-Fl”te erg„nzt werden!
/*03.07.2008 17:18 zum Ersetzen von Variablenbezeichnungen in einem Text durch den Variablenwert
      Die Bezeichnung muss von einem $ angefhrt werden und mit einem Space enden: z.B. $1->auftrnr ...
      Vielleicht kann man auch Funktionen einbauen, indem man sie in Klammern setzt?: auch ohne!!*/
   /* Variablen-Namen: entweder Feldvariablen der aktuellen WorkArea, z.B. $(
                       oder bei "N" mit LenDec am Ende, z.B. 62 
                       "N"-Variable mssen im Text in Klammern stehen: $(nRate62) */
  /*12.10.2022 14:11 IMMER die Variablen in Klammern() setzen, denn 'FieldInfo(FieldPos(SubStr' verl„sst sich darauf.*/
//15.02.2026 18:18 abgeglichen mit VariPosition_2: 
FUNCTION VariPosition_1( cString, cContainer, cFont, cFSize, cFormSeite, cZeileCM, cFile)	//28.09.2023 12:51 cFAV ??
   LOCAL CR := Chr(13), LF := Chr(10)
   LOCAL nVarLenR, nVarLen, nTabLen := 0
   LOCAL nPosition, cPosition, aPosition := {}, nAnf, nEnd, aPos := {0,0}, nTop, nLeft
   LOCAL mmpx := 0.352778		//0.2835	// mm pro Pixel 
   LOCAL nFSize := Val(cFSize), nFHoehe := nFSize * 0.352778, nFBreite := nFSize * 0.195	// 0.2 ist ein gesch„tzter vorl„ufiger Wert
   LOCAL nZeileMM := IIf(Val(cZeileCM)<0.2, nFHoehe * Val(cZeileCM)*10, Val(cZeileCM)*10)		// nZeileMM aus cZeileCM berechnen
   LOCAL aFormSeite := {}
   LOCAL cPos1 := "0", cPos2 := "0", cMargTopCM := "0", cSpace := "", cMargLeftCM := "0"
   LOCAL cEingabeCM := "0", nEingabeVor := 0	//18.12.2022 21:09
   LOCAL cVarInhalt
   LOCAL oProgress	//03.03.2024 21:32
   LOCAL cEFSize := LTrim(Str(nFSize-1))+"pt"	//04.09.2023 16:43 FontSize der Eingabefelder
   LOCAL cInpZeileCM := Max("0.59",LTrim(Str((nFSize-1)*mmpx*0.12)))+"cm"	//04.09.2023 16:44	Zeilenh”he der Eingabefelder
   LOCAL cTextHoeheCM := ""
   LOCAL cFormular, nSO := 0			//21.10.2023 12:38	nSO ist der SeitenOffset der DIVabs fr die weiteren Seiten
	LOCAL cRahmID, cBildALT			//30.10.2023 12:44
	LOCAL check := '', cRadioName := "Radio0"		//18.11.2023 14:59 checked == groáes X fr CheckBox ist angehakt
	LOCAL nFormS, aFormSize, aF_Info,cInpSize, cETFSize, nHDiff	//19.02.2024 16:31 nachtr„glich als LOCAL erkl„rt
	LOCAL cTopCM, cLeftCM, nDIV, nFONT, nINP, nTXT, nDivCM, cDivCM	//19.02.2024 16:31 nachtr„glich als LOCAL erkl„rt
	LOCAL cTA, cTAFont, aTFSize, nAB		//19.02.2024 16:31 nachtr„glich als LOCAL erkl„rt
   PRIVATE cVariable, xVariable, nSp := 0	//03.09.2023 13:42 fr die id der SPANs 
	PRIVATE aGruen 			//19.12.2023 18:57 speziell fr Mllers Grnfl„chenFormular
	PRIVATE cFC := "", cFS := cFSize, cFF := cFont	//20.02.2024 14:33 fr Font-Žnderungen
	PRIVATE cFB := Str(nFBreite)	//07.03.2024 21:51
	
   DEFAULT cContainer TO ""

	nFBreite := FontBreite(cFont,cFSize,"M")	//28.12.2022 14:26 Buchstabenbreite aus aTextBox ausgerechnet
	nInpFBreite := FontBreite(cFont,cEFSize,"M")	//10.02.2024 16:23 cEFSize,"M"
	
	// berechnet den Anfangs-Top-Abstand aus cFormSeite/InditextF.txt^ vvvvvvvvvvvvvvvvvvvvvvvv
	// wie bei php: aPosition = explode(cPosition)
	DO WHILE (nFormS := At(" " , cFormSeite)) > 0
		AAdd(aFormSeite, Val(SubStr(cFormSeite, 1, nFormS-1)))
		cFormSeite := SubStr(cFormSeite, nFormS+1)
	ENDDO
	IF Len(cFormSeite) > 0
		AAdd(aFormSeite, Val(cFormSeite))
	ENDIF
	nTop := IIf(Len(aFormSeite)>4,aFormSeite[2],IIf(Len(aFormSeite)==4,aFormSeite[1],0))
	nLeft := IIf(Len(aFormSeite)>4,aFormSeite[5],IIf(Len(aFormSeite)==4,aFormSeite[4],0))
   //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

      //+03.03.2024 21:33 Fortschrittsanzeige
      oProgress := ProgressBar():new( AppDeskTop(),, {400,350}, {AppDeskTop():currentsize()[1]-800,24},, .F. )
      oProgress:create()
      oProgress:color   := GRA_CLR_GREEN
      oProgress:minimum := 1
      oProgress:maximum := 20

	cContainer += ''
   DO WHILE At("$",cString) > 0
   	// die Positionierung der Variablen |left,top,width,height|
   	aPosition := {}
		cEingabeCM := "0"		//27.09.2023 10:21 von hinten hierhin (wegen 'gespeicherte Daten in Inputfelder')
		cTextHoeheCM := ""	//05.10.2023 18:50
		
      /* der Variablen-Name:*/
      cVariable := SubStr( cString, At("$",cString)+1, At(") ",cString,At("$",cString))-At("$",cString) )
		nVarLenR := Len(cVariable)		// fr Ersetzung in der Variablen cString s.u.

		//19.02.2024 18:29 um die Font-Parameter zu ver„ndern
		IF "FNT_SET"$Upper(cVariable) .OR. "FONT"$Upper(cVariable)
			cFS := cFSize		// PRIVATE, damit &cVariable sie verwenden kann
			cFF := cFont
			IF "FNT_SET"$Upper(cVariable)
				cVariable := SubStr(cVariable,2,Len(cVariable)-2)		// Font-Berechnung
				xyz := &cVariable
			ELSE
			//	cVariable := '$(FONT("12pt","Times italic"))'
				nAnf := At('FONT(',cVariable)+6
				nEnd := At('","',cVariable)
				cFS := SubStr(cVariable,nAnf,nEnd-nAnf)
				nAnf := nEnd+3
				nEnd := Len(cVariable)-2
				cFF := SubStr(cVariable,nAnf,nEnd-nAnf)
			ENDIF
	   	cString := Stuff(cString,At("$",cString),nVarLenR+1,"")	// komplett l”schen
	   	cFSize := cFS			//02.03.2024 13:44
	   	cFont := cFF			//02.03.2024 13:44
			nFSize := Val(cFSize)
			nFHoehe := nFSize * 0.352778
			nZeileMM := IIf(Val(cZeileCM)<0.2, nFHoehe * Val(cZeileCM)*10, Val(cZeileCM)*10)		// nZeileMM aus cZeileCM berechnen
	   	nFBreite := FontBreite(cFont,cFSize,"W")	//02.03.2024 13:44
	   	cFB := Str(nFBreite)
	         oProgress:increment()      //+03.03.2024 21:28
	   	LOOP
		ENDIF
			      
      IF Len(cVariable)>=5 .AND. (","$cVariable .OR. "{||"$cVariable .OR. "->"$cVariable)
			IF (At("{|",cVariable)>0 .AND. At("})",cVariable)>0)		//29.08.2023 19:10 wenn ein CodeBlock drin ist ohne Position
				cPosition := "0,0"
				cVariable := SubStr(cVariable,2,Len(cVariable)-2)
			ELSEIF !","$cVariable .OR. (At("{||",cVariable)>0 .AND. At("}",cVariable) > RAt(",",cVariable))	// wenn komma nur im Codeblock
				cPosition := "0,0"																									// -> keine Position
				cVariable := SubStr(cVariable,2,Len(cVariable)-2)
			ELSEIF "')"$cVariable .AND. At(")",cVariable) > RAt(",",cvariable)			// literal String ohne Position
				cPosition := "0,0"																		// -> keine Position
				cVariable := SubStr(cVariable,2,Len(cVariable)-2)
			ELSEIF "))"$cVariable .AND. At("))",cVariable) == Len(cVariable)-1			// Function ohne Position
				cPosition := "0,0"																		// -> keine Position
				cVariable := SubStr(cVariable,2,Len(cVariable)-2)
			ELSE
				IF At("{|",cVariable)>0 .AND. At("IIf(",cVariable,At("{|",cVariable)+1)>0			//02.04.2024 14:57
					nAnf := RAt(")},",cVariable)+3
				ELSEIF At("IIf(",cVariable)>0			//05.03.2024 13:24
			//		nAnf := Max(At("),",cVariable)+2,At(")),",cVariable)+3,RAt("),",cVariable)+2)
					nAnf := RAt("),",cVariable)+2
				ELSEIF !"{|"$cVariable .AND. At("(",cVariable,3)>5 .AND.  RAt("),",cVariable)<(Len(cVariable)-5)	//18.03.2024 10:18
					nAnf := RAt("),",cVariable)+2									// fr Funktionen mit Position
				ELSEIF At("('",cVariable)>0 .AND.  At("',",cVariable)>0	//04.03.2024 13:03
					nAnf := At("',",cVariable)+2 	// fr literale Texte
				ELSEIF At("{|",cVariable)>0 .AND. At("}",cVariable) < RAt(",",cVariable)			// Komma auch hinter dem Codeblock
					nAnf := At(",",cVariable,At("}",cVariable))+1		//Codeblock
				ELSEIF (nAnf := RAt(')',cVariable,Len(cVariable)-1)) > 0			//cVariable = Function
					nAnf += 2
				ELSE
					nAnf := At(",",cVariable)+1								//Variable
				ENDIF 
				nEnd := Len(cVariable)
				cPosition := SubStr(cVariable,nAnf,nEnd-nAnf)
				cVariable := SubStr(cVariable,2,nAnf-3)				// isoliert die Variable/den CodeBlock
			ENDIF
			// berechnet die absolute Lage der Variablen auf der Seite:   vvvvvvvvvvvvvvvvvvvvvvvvvvv
			// wie bei php: aPosition = explode(cPosition)
			DO WHILE (nPosition := At("," , cPosition)) > 0
				AAdd(aPosition, Val(SubStr(cPosition, 1, nPosition-1)))
				cPosition := SubStr(cPosition, nPosition+1)
			ENDDO
			IF Len(cPosition) > 0 .AND. Val(cPosition) != 0
				AAdd(aPosition, Int(Val(cPosition) - nZeileMM * 10))	// -nZeileMM, weil die Einstellung.txt die Werte vom Unterstrich hat... 
			ELSEIF Len(cPosition) > 0
				AAdd(aPosition,0)
			ENDIF																//				...w„hrend ein SPAN/DIV seine Positionswerte oben links hat
			// hier ggf. einfgen die fehlenden Parameter width und height 
			// hat die Variable auf der Seite eine feste L„nge? = width: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
			//27.09.2023 10:19 damit gespeicherte Falldaten in Input-Felder des Formulars gesteckt werden
			IF Len(aPosition)==4	//21.12.2023 13:33 wenn ein Textfeld
				cTextHoeheCM := LTrim(Str(aPosition[1]/100))+"cm"
				cEingabeCM := LTrim(Str(aPosition[2]/100))+"cm"
				aRemove(aPosition,1)
				aRemove(aPosition,1)
			ELSEIF Len(aPosition)==3	//13.11.2023 18:26 wenn ein Inputfeld
				cEingabeCM := LTrim(Str(aPosition[1]/100))+"cm"
				aRemove(aPosition,1)
			ENDIF
      	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
			//29.08.2023 20:59 fhrt den CodeBlock aus und macht daraus eine literale String mit Hilfe Chr(39)
			IF "{|"$cVariable
				xVariable := Eval(&cVariable)	// 29.08.2023 19:19 den CodeBlock ausfhren
				IF ValType(xVariable) == "C"
					cVariable := Chr(39)+xVariable+Chr(39)
				ELSEIF ValType(xVariable) == "N"
					cVariable := Chr(39)+AllTrim(Str(xVariable))+Chr(39)
				ELSEIF ValType(xVariable) == "D"
					cVariable := Chr(39)+DtoC(xVariable)+Chr(39)
				ELSEIF ValType(xVariable) == "L"
					cVariable := Chr(39)+Chr(39)
				ENDIF
			ENDIF
		ELSEIF ".PNG"$Upper(cVariable)	// 19.10.2023 18:56 Formular fr die zweite Seite
			nSO += 1		//Seitenoffset fr die DIVabs-Felder der weiteren Seiten
			cRahmID = "Rahmen"+LTrim(Str(1+nSO))
			cBildALT = "Bild"+LTrim(Str(1+nSO))
			cFormular := 'F/'+SubStr(cVariable,3,Len(cVariable)-4)
			aFormSize := FormSize(cFormular)	//02.11.2023 10:58
			cFormular := '../../../../'+cFormular

			cContainer += '
'+CR+LF cContainer += '
'+CR+LF cContainer += '
'+CR+LF cContainer += ''+cBildALT+'' cContainer += '
'+CR+LF cVarInhalt := "" cString := Stuff(cString,At("$",cString),nVarLenR+1,cVarInhalt) // ersetzt in cString die Variablenbezeichnung durch ihren Inhalt LOOP ELSE cVariable := SubStr( cVariable, At("(",cVariable)+1, At(")",cVariable,At("(",cVariable))-At("(",cVariable)-1 ) aPosition := {0,0} // vorl„ufig ... ENDIF /* die L„nge des Namens der Variablen: */ nVarLen := Len(cVariable) IF Len(AllTrim(cVariable)) == 0 cVarInhalt := "" ELSEIF CRLF$cVariable // kommt nur bei Texten in ** vor cVariable := Stuff(cVariable,At("'",cVariable),1,"") cVarInhalt := Stuff(cVariable,At("'",cVariable),1,"") // der cVarInhalt ist gleich der 'cVariablen' ohne die '' ELSEIF RAt("')",cVariable)==Len(cVariable)-1 //10.09.2023 15:31 wenn am Ende ') steht, also Literal cVarInhalt := &cVariable ELSEIF RAt(')',cVariable,Len(cVariable)-1) > 0 //cVariable = Function cVarInhalt := &cVariable ELSEIF Val(cEingabeCM) > 0 .AND. Val(cVariable) > 100 //05.10.2023 18:40 cTextHoeheCM := Str(Val(cVariable)/100)+"cm" cVarInhalt := "" ELSE IF TYPE(cVariable)$"UE" msgbox("Fehler bei der Variablen:"+cVariable) cString := Stuff(cString,At("$",cString),nVarLen,"X X X X X") LOOP ENDIF IF Val(cVariable) < 20 //18.12.2022 20:43 wenn es KEIN Eingabefeld ist //13.12.2023 14:30 testweise cVariable = IIf("IIF"==SubStr(Upper(cVariable),0,3),&cVariable,cVariable) //28.08.2023 09:41 Testweise aF_Info := IIf("->"$cVariable .AND. ValType(&cVariable)=="N", F_Info(cVariable), {,}) //28.03.2023 19:06 FieldInfo() cVarInhalt := IIf(ValType(&cVariable)$"CM", ; ; /* ... dann StringVariable mit AllTrim komprimieren: */ AllTrim(&cVariable), ; ; /* NumVariable in Strings verwandeln: */ IIf(ValType(&cVariable)=="N", ; ; /* Mem- oder Feldvariable? */ IIf("->"$cVariable, ; ; /* Feldvariable: Dezimalstellen aus FieldInfo holen: */ Str(&cVariable, ; /*12.10.2022 13:59 nVarLen-6 als nCount fr Substr(cVariable) 4mal in VariFunkErsatz_1() */ aF_Info[1], ; /* FieldInfo(FieldPos(SubStr(cVariable,At(">",cVariable)+1,nVarLen-3)),FLD_LEN), ; */ aF_Info[2] ; /* FieldInfo(FieldPos(SubStr(cVariable,At(">",cVariable)+1,nVarLen-3)),FLD_DEC) ; */ ), ; ; /* Memvariable: Dezimalstellen aus 2stelliger Zahl holen: */ Str(&cVariable, ; Val(cVariable[At(")",cVariable)-2]), ; Val(cVariable[At(")",cVariable)-1]) ; ) ; ), ; ; /* Datumsvariable in String verwandeln */ IIf(ValType(&cVariable)=="D", ; DtoC(&cVariable), ; IIf( Upper(cVariable[1])$"D", ; DtoC( DATE() + Val(SubStr(cVariable,2))), ; "" ; ) ; ) ; ) ; ) cVarInhalt := AllTrim(cVarInhalt) //31.08.2023 21:53 hierher von hinten //24.12.2022 09:10 +" " ELSE cEingabeCM := LTrim(Str(Val(cVariable)/100))+"cm" cVarInhalt := "" //04.11.2023 16:41 Eingabefeld Space(Val(cVariable)/10/nFBreite) //23.12.2022 15:43 ENDIF ENDIF cString := Stuff(cString,At("$",cString),nVarLenR+1,cVarInhalt) // diese Zeile scheint nicht mehr gebraucht zu werden. DOCH! //12.11.2024 14:14: // DO WHILE CRLF$cVarInhalt // cVarInhalt := Stuff(cVarInhalt,At(CRLF,cVarInhalt),2,"
") // ENDDO //27.09.2023 12:23 Formular-Aufbau mit absolut-positionierten DIVs: cInpSize := LTrim(Str(Max(Len(cVarInhalt),Int(Val(cEingabeCM)*10/nFBreite)))) cETFSize := LTrim(Str(nFSize-2))+"pt" // noch kleiner als cEFSize cInpZeileCM := LTrim(Str((nFSize)*mmpx*0.12,5,3))+"cm" //04.09.2023 16:44 Zeilenh”he der Eingabefelder //25.01.2024 18:02 formatiert:5,3 nHDiff := (Val(cZeileCM)-Val(cInpZeileCM))*100 //03.11.2023 19:58 cTopCM := LTrim(Str((aPosition[2]+nHDiff)/100))+"cm" //03.11.2023 20:00 +nHDiff -Input um nHDiff nach unten schieben cLeftCM := LTrim(Str(aPosition[1]/100))+"cm" nDIV := RAt('
',cContainer) // letztes DIV nFONT := RAt('
',cContainer) //17.02.2024 20:59 letztes FONT im DIV nINP := RAt('" />
',cContainer) // letztes Input nTXT := RAt('
',cContainer) // letzte textarea IF aPosition[1] == 0 .AND. (aPosition[2]==0 .OR. aPosition[2]==aPos[2]) .AND. Len(cVarInhalt) > 0 .AND. nDIV > nINP+5 .AND. nDIV > nTXT+12 // wenn keine Positionsangabe, dann anh„ngen an vorige DIV, wenn die keine Input/Textarea enth„lt //23.01.2024 dazu muss die width des DIVs vergr”áert werden: //20.02.2024 18:53 wenn die keinen festen Wert hat und nicht ^ oder > passiert: IF (RAt('text-align:center',cContainer) > RAt('
RAt('
RAt('
0 .AND. nFONT < nDIV //17.02.2024 21:02 cContainer := Stuff(cContainer,RAt("
",cContainer), 0, IIf(cVarInhalt[1]==",", cVarInhalt, " "+cVarInhalt)) ELSE cContainer := Stuff(cContainer,RAt("
",cContainer), 0, IIf(cVarInhalt[1]==",", cVarInhalt, " "+cVarInhalt)) ENDIF aPos[1] += FontBreite(cFont,cFSize,cVarInhalt+"W") // aPos[1] += Len(cVarInhalt+" ") * nFBreite * 10 //03.03.2024 13:47 " " ELSEIF aPosition[1] == 0 .AND. (aPosition[2]==0 .OR. aPosition[2]==aPos[2]) .AND. Len(cVarInhalt) > 0 // wenn keine Positionsangabe, dann anh„ngen an vorige INP IF nINP > nTXT nAnf := RAt('value="',cContainer)+7 nEnd := RAt('" />
',cContainer) nTA := nEnd-nAnf cVarInh := AllTrim(SubStr(cContainer,nAnf,nEnd-nAnf)) IF RAt('text-align:center',cContainer) > RAt('
RAt('
',cContainer)-RAt('value="',cContainer)-7, cVarInhalt) // cContainer := Stuff(cContainer,RAt('" />
',cContainer), 0, IIf(cVarInhalt[1]==',', cVarInhalt+' ', ' '+cVarInhalt)) ELSE cVarInh := AllTrim(SubStr(cContainer,RAt('',cContainer)-RAt('',cContainer)-RAt('
',cContainer), 0, IIf(cVarInhalt[1]==',', cVarInhalt+' ', ' '+cVarInhalt)) ENDIF //bleibt gleich!! aPos[1] += Len(cVarInhalt) * nFBreite * 10 ELSEIF Len(aPosition) == 2 // muss fr sich positioniert werden IF cVarInhalt == "SENDEN" cContainer += '
' cContainer += '
'+CR+LF aPos[1] := aPosition[1]+300 // weil der Knopf 3cm breit sit aPos[2] := aPosition[2] ELSEIF Val(cEingabeCM) == 0 .OR. cAusfuell == "HTML" // keine Eingabe-L„nge, wieso also INPUT ??? (immerhin readonly) IF !Empty(cVarInhalt) .AND. cVarInhalt[1]==">" //11.02.2024 18:01 rechtsbndig, z.B. Euro cVarInhalt := IIf(Len(cVarInhalt)>1,SubStr(cVarInhalt,2),"") //14.02.2024 12:52 > + nix = "" IF cAusfuell == "HTML" .AND. Val(cEingabeCM) > 0 //18.02.2024 13:54 cDivCM := cEingabeCM ELSE // cDivCM := LTrim(Str(Len(cVarInhalt+" ")*nFBreite/10))+"cm" cDivCM := LTrim(Str(FontBreite(cFont,cFSize,cVarInhalt+"W")))+"cm" ENDIF cLeftCM = LTrim(Str(Val(cLeftCM)-Val(cDivCM)))+"cm" cTA := "text-align:right;" ELSEIF !Empty(cVarInhalt) .AND. cVarInhalt[1]=="^" //11.02.2024 18:01 zentriert, z.B. Spalten cVarInhalt := IIf(Len(cVarInhalt)>1,SubStr(cVarInhalt,2),"") //14.02.2024 12:52 > + nix = "" IF cAusfuell == "HTML" .AND. Val(cEingabeCM) > 0 //18.02.2024 13:54 cDivCM := cEingabeCM ELSE // cDivCM := LTrim(Str(Len(cVarInhalt+" ")*nFBreite/10))+"cm" cDivCM := LTrim(Str(FontBreite(cFont,cFSize,cVarInhalt+"W")))+"cm" ENDIF cLeftCM = LTrim(Str(Val(cLeftCM)-Val(cDivCM)/2))+"cm" cTA := "text-align:center;" ELSE IF cAusfuell == "HTML" .AND. Val(cEingabeCM) > 0 //18.02.2024 13:54 cDivCM := cEingabeCM ELSE // cDivCM := LTrim(Str(Len(cVarInhalt+" ")*nFBreite/10))+"cm" //17.02.2026 18:44 cDivCM := LTrim(Str(FontBreite(cFont,cFSize,cVarInhalt+Space(Max(1,Len(cVarInhalt)/10))),5,2))+"cm" cDivCM := LTrim(Str(FontBreite(cFont,cFSize,cVarInhalt+"WW"),5,2))+"cm" //17.02.2026 18:45 "W" ENDIF cTA := "" ENDIF cTAFont := IIf("right"$cTA .AND. cAusfuell == "PDF","Courier",cFont) //12.02.2024 12:39 //18.02.2024 10:58 PDF // das ist tats„chlich transparent (0.01): background-color:rgba(255,255,255,0.01) cContainer += '
' IF cAusfuell == "HTML" //18.02.2024 10:51 ausfllen mit LO, daher // IF !Empty(cVarInhalt) .AND. "C"==Upper(cVarInhalt[1]) .AND. "X"==Upper(cVarInhalt[Len(cVarInhalt)]) // check := IIf(cVarInhalt=="X",'checked="checked"',"") // cContainer += '
'+CR+LF // ELSEIF !Empty(cVarInhalt) .AND. "R"==Upper(cVarInhalt[1]) .AND. "X"==Upper(cVarInhalt[Len(cVarInhalt)]) // check := IIf(cVarInhalt[Len(cVarInhalt)]=="X",'checked="checked"',"") // cRadioName := SubStr(cVarInhalt,1,Len(cVarInhalt)-1) // cContainer += '
'+CR+LF // ELSE // aTFSize := {"1","2","3","4","5","6","7","1","1","2","2","3","3","4","4","4","5","5","5","5","6","6","6","6","6","6","6","6","7","7","7","7","7","7","7","7","7"} //17.02.2024 20:42 cVarInhalt := IIf(cVarInhalt=="Cx"," ",IIf(cVarInhalt=="CX","X",cVarInhalt)) //18.02.2024 14:31 cVarInhalt := IIf(Len(cVarInhalt)==3 .AND. cVarinhalt[1]=="R" .AND. Upper(cVarInhalt[3])=="X",IIf(cVarInhalt[3]=="X","X"," "),cVarInhalt) //18.02.2024 14:31 IIF("ITALIC"$Upper(cFF),{cIt1:="",cIt2:=""},{cIt1:="",cIt2:=""}) //13.11.2024 14:08 IIF("BOLD"$Upper(cFF),{cBd1:="",cBd2:=""},{cBd1:="",cBd2:=""}) //13.11.2024 14:08 IF Val(cFS) < 8 .AND. Len(cFS) == 1 cContainer += ''+cIt1+cBd1+cVarInhalt+cBd2+cIt2+'
'+CR+LF ELSE cContainer += ''+cIt1+cBd1+cVarInhalt+cBd2+cIt2+'
'+CR+LF ENDIF ELSE cContainer += cVarInhalt+''+CR+LF ENDIF //24.09.2023 12:14 berschreibt fr Inputfelder: aPos[1] := aPosition[1] + Len(cVarInhalt)*nFBreite*10 aPos[2]=aPosition[2] ELSEIF Val(cTextHoeheCM) > 0 // '+CR+LF //24.09.2023 12:14 berschreibt fr Inputfelder: aPos[1] := aPosition[1] + Val(cEingabeCM)*100 //24.09.2023 12:15 aPos[2]=aPosition[2] ELSE // == IMMER PDF IF !Empty(cVarInhalt) .AND. cVarInhalt[1]==">" //11.02.2024 18:01 rechtsbndig, z.B. Euro cVarInhalt := IIf(Len(cVarInhalt)>1,SubStr(cVarInhalt,2),"") //14.02.2024 12:52 > + nix = "" cDivCM := LTrim(Str(Len(cVarInhalt+" ")*nFBreite/10))+"cm" //22.02.2024 09:39 cLeftCM = LTrim(Str(Val(cLeftCM)-Val(cEingabeCM)))+"cm" cTA := "text-align:right;" cContainer += '
' ELSEIF !Empty(cVarInhalt) .AND. cVarInhalt[1]=="^" //11.02.2024 18:01 zentriert, z.B. Spalten cVarInhalt := IIf(Len(cVarInhalt)>1,SubStr(cVarInhalt,2),"") //14.02.2024 12:52 ^ + nix = "" cTA := "text-align:center;padding:auto;" cContainer += '
' ELSE // das ist tats„chlich transparent: background-color:rgba(255,255,255,0.01); cTA := "" cContainer += '
' ENDIF IF !Empty(cVarInhalt) .AND. "C"==Upper(cVarInhalt[1]) .AND. "X"==Upper(cVarInhalt[Len(cVarInhalt)]) check := IIf(cVarInhalt=="X",'checked="checked"',"") cContainer += '
'+CR+LF ELSEIF !Empty(cVarInhalt) .AND. "R"==Upper(cVarInhalt[1]) .AND. "X"==Upper(cVarInhalt[Len(cVarInhalt)]) check := IIf(cVarInhalt[Len(cVarInhalt)]=="X",'checked="checked"',"") cRadioName := SubStr(cVarInhalt,1,Len(cVarInhalt)-1) cContainer += '
'+CR+LF ELSE //das sollte transparent sein(0.01 !!): border-color:rgba(255,255,255,0.01);background-color:rgba(255,255,255,0.01); IF "right"$cTA cTAFont := "Courier" nAB := Int(Val(cEingabeCM)*10 / FontBreite(cTAFont,cETFSize)+1) //FontBreite ist in mm! cVarInhalt := PadL(cVarInhalt,nAB) ELSEIF "center"$cTA cTAFont := "Courier" nAB := Int(Val(cEingabeCM)*10 / FontBreite(cTAFont,cETFSize)+1) //FontBreite ist in mm! cVarInhalt := PadC(cVarInhalt,nAB) ELSE cTAFont := cFont ENDIF cContainer += '
'+CR+LF ENDIF //24.09.2023 12:14 berschreibt fr Inputfelder: aPos[1] := aPosition[1] + Val(cEingabeCM)*100 //24.09.2023 12:15 aPos[2]=aPosition[2] ENDIF ENDIF nEingabeVor := Val(cEingabeCM) oProgress:increment() //+03.03.2024 21:33 ENDDO oProgress:destroy() //+03.03.2024 21:33 /* IF nSO > 0 cContainer += '' ENDIF*/ RETURN cString FUNCTION FNT_set(cParnam1,cWert1,cParnam2,cWert2) cParnam1 := cWert1 IF !Empty(cParnam2) .AND. !Empty(cWert2) cParnam2 := cWert2 ENDIF RETURN .T. //06.11.2022 19:22 Adresse aus vers.dbf zusammenstellen fr html-Briefe //19.03.2024 16:47 nA == Area, also 1,5,12 - als Zahl FUNCTION BriefAdresse(nArt,cVerskz,nA) // nArt=1 heiát als Block, nArt=2 heiát in einer Zeile LOCAL cAdresse := "" DEFAULT nArt TO 1 DEFAULT cVerskz TO "FH001" DEFAULT nA TO 5 cVerskz := AllTrim(cVerskz) // cVerskz := AllTrim(ConvToOEMCP(cVerskz)) IF cVerskz == "A" // Adressat ist der Ansprechpartner IF nArt == 1 cAdresse += AllTrim(Anrede()) + CRLF cAdresse += AllTrim(1->ansp_vname) + " " + AllTrim(1->ansp_name) + CRLF cAdresse += AllTrim(1->ansp_str) + CRLF cAdresse += AllTrim(1->ansp_ort) + CRLF ELSEIF nArt == 2 cAdresse += AllTrim(1->ansp_anr) + " " + AllTrim(1->ansp_vname) + " " + AllTrim(1->ansp_name) + ", " + AllTrim(1->ansp_str) + ", " + AllTrim(1->ansp_ort) ELSEIF nArt == 3 cAdresse += AllTrim(1->ansp_anr) + " " + AllTrim(1->ansp_vname) + " " + AllTrim(1->ansp_name) + " " + AllTrim(1->ansp_str) + " " + AllTrim(1->ansp_ort) ENDIF ELSEIF cVerskz == "E" // Adressat ist der Ansprechpartner IF nArt == 1 cAdresse += AllTrim(Anrede(IIf(1->anrede="Frau ","Herr ","Frau "))) + CRLF // trailing Space ist wichtig! cAdresse += AllTrim(1->eh_vname) + " " + AllTrim(1->ansp_name) + CRLF cAdresse += AllTrim(1->eh_str) + CRLF cAdresse += AllTrim(1->eh_ort) + CRLF ELSEIF nArt == 2 cAdresse += AllTrim(1->eh_anr) + " " + AllTrim(1->eh_vname) + " " + AllTrim(1->eh_name) + ", " + AllTrim(1->eh_str) + ", " + AllTrim(1->eh_ort) ELSEIF nArt == 3 cAdresse += AllTrim(1->eh_anr) + " " + AllTrim(1->eh_vname) + " " + AllTrim(1->eh_name) + " " + AllTrim(1->eh_str) + " " + AllTrim(1->eh_ort) ENDIF ELSE IF Len(cVerskz) < 6 .AND. Len(AllTrim(cVerskz)) > 0 IF !(nA)->(DbSeek(cVerskz,.F.)) RETURN cVerskz ENDIF ELSE (nA)->(DbGotop()) IF Len(AllTrim(cVerskz)) == 0 .OR. !(nA)->(DBLocate( {|| cVerskz $ ((nA)->name1 + (nA)->name2) .OR. cVerskz $ (AllTrim((nA)->name1) +" "+ AllTrim((nA)->plz_ort)) } )) RETURN cVerskz ENDIF ENDIF IF nArt == 1 cAdresse += AllTrim((nA)->name1) + CRLF cAdresse += AllTrim((nA)->name2) + CRLF cAdresse += AllTrim((nA)->strasse) + CRLF cAdresse += AllTrim((nA)->plz_ort) + CRLF ELSEIF nArt == 2 cAdresse += AllTrim((nA)->name1) + " " + AllTrim((nA)->name2) + ", " + AllTrim((nA)->strasse) + ", " + AllTrim((nA)->plz_ort) ELSEIF nArt == 3 cAdresse += AllTrim((nA)->name1) + " " + AllTrim((nA)->name2) + " " + AllTrim((nA)->strasse) + " " + AllTrim((nA)->plz_ort) ENDIF ENDIF RETURN cAdresse //29.10.2022 17:56 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //FUNCTION ModalFen( cString, cTitle, oDlg1, nXsize, nYsize ) FUNCTION ButtonFenster( aInditxt, oDlg1 ) LOCAL nEvent, mp1, mp2, oXbp, lExit LOCAL oDlg, oSle, oMle, oFocus, aPos, nSemi := 0 //, drawingArea LOCAL drawingArea := oDlg1:drawingArea //* LOCAL aSize := drawingArea:currentSize() LOCAL nXsize := ASize[1]*0.6 LOCAL nYsize := 200 + Len(aInditxt) * 25 LOCAL nText := 0 LOCAL cTitle := "W„hlen Sie einen Brief aus ! - (Edit mit ALT-Taste)" // cString := IIf( cString<>NIL, cString, "Datensatz "+LTrim(Str(Recno()))+" ist z.Zt. gesperrt!" ) oDlg1 := IIf( oDlg1<>NIL, oDlg1, AppDesktop() ) drawingArea := oDlg1:drawingArea //* aSize := drawingArea:currentSize() aPos := { ( aSize[1]-nXsize )/2, ( aSize[2]-nYsize+20 ) / 2 } oDlg := AKDialog():new( AppDesktop(), oDlg1, aPos, {nXsize,nYsize} ) oDlg:title := cTitle oDlg:taskList := .T. oDlg:minButton := .F. oDlg:maxButton := .F. oDlg:create() // oDlg:drawingArea:setColorBG( GRA_CLR_YELLOW ) oFocus := SetAppFocus( oDlg ) aSize := oDlg:drawingArea:currentSize() nAnztxt := Len(aInditxt) FOR i:=1 TO nAnztxt aPos := { 10, 30 * (nAnztxt-i+1) } oButt := ("oXbpB"+LTrim(Str(i))) &oButt:= XbpPushbutton():new( oDlg:drawingArea,, aPos, {aSize[1]-10,24} ) &oButt:caption := aInditxt[i] &oButt:TabStop := .T. &oButt:create() &oButt:activate := {|| PostAppEvent( xbeP_Close, i,, &oButt ) } &oButt:cargo := i NEXT oDlg:setModalState( XBP_DISP_APPMODAL ) oDlg:show() nEvent := xbe_None DO WHILE nEvent <> xbeP_Close nEvent := AppEvent( @mp1, @mp2, @oXbp ) IF nEvent == xbeM_LbDown nText := oXbp:cargo ENDIF IF nEvent == xbeP_Keyboard DO CASE CASE mp1 == xbeK_ESC cString := "ESC" PostAppEvent( xbeP_Activate,,, &oButt ) CASE mp1 == xbeK_RETURN .OR. mp1 == xbeK_F10 cString := "!" PostAppEvent( xbeP_Activate,,, &oButt ) ENDCASE ENDIF oXbp:handleEvent( nEvent, mp1, mp2 ) ENDDO oDlg:setModalState( XBP_DISP_MODELESS ) oDlg:destroy() // SetAppFocus( oFocus ) RETURN nText //^^ButtonFenster^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //16.03.2023 16:45 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //FUNCTION ModalFen( cString, cTitle, oDlg1, nXsize, nYsize ) FUNCTION ListboxFenster( aInditxt, oDlg1, cFormName, nBreite) LOCAL nEvent, mp1, mp2, oXbp, lExit LOCAL oDlgLF, oFocus, aPos //, drawingArea LOCAL drawingArea := oDlg1:drawingArea, oDlgDA //* 16.03.2023 18:34 oDlgDA LOCAL aSize := drawingArea:currentSize() LOCAL nXsize := ASize[1]* IIf(Empty(nBreite), 0.6, nBreite) //08.01.2024 11:51 LOCAL nYsize := ASize[2]*0.8 LOCAL nText := 0 LOCAL cTitle := "W„hlen Sie ein Formular aus ! - (zum Editieren mit ALT-Taste in den Editor laden)" oDlg1 := IIf( oDlg1<>NIL, oDlg1, AppDesktop() ) drawingArea := oDlg1:drawingArea //* aSize := drawingArea:currentSize() aPos := { ( aSize[1]-nXsize )/2, ( aSize[2]-nYsize+20 ) / 2 } oDlgLF := AKDialog():new( AppDesktop(), oDlg1, aPos, {nXsize,nYsize} ) oDlgLF:title := cTitle oDlgLF:taskList := .T. oDlgLF:minButton := .F. oDlgLF:maxButton := .F. oDlgLF:create() oDlgLF:lockupdate(.T.) //+27.11.2011 09:20 oDlgDA = oDlgLF:drawingArea oDlgDA:setColorBG( GRA_CLR_YELLOW ) oFocus := SetAppFocus( oDlgLF ) aSize := oDlgDA:currentSize() oListBox := XbpListBox():new( oDlgDA,,{Int(12*nV),Int(12*nV)},{aSize[1]-Int(20*nV),aSize[2]-Int(20*nV)}) Sleep(2) //+16.08.2012 10:56 Vista-Problem ! oListBox:setFontCompoundName( cBFont ) oListBox:create() Sleep(2) //+16.08.2012 10:56 Vista-Problem ! FOR i := 1 TO Len(aInditxt) oListBox:addItem(ConvToOEMCP(aInditxt[i])) // oListBox:addItem(aInditxt[i]) Sleep(2) //+23.02.2010 08:58 Vista-Problem ! NEXT //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ oListBox:setData( {1}, .T. ) oDlgLF:lockupdate(.F.) //+27.11.2011 09:20 oDlgLF:invalidateRect() //+27.11.2011 09:30 oDlgLF:setModalState( XBP_DISP_APPMODAL ) oDlgLF:show() SetAppFocus(oListBox) nEvent := xbe_None DO WHILE nEvent <> xbeP_Close nEvent := AppEvent( @mp1, @mp2, @oXbp ) IF nEvent == xbeM_LbDblClick .and. oXbp:isDerivedFrom( "XbpListBox" ) cFormName := oListBox:getItem( oListBox:getData()[1] ) nText := oListBox:getData()[1] nEvent := xbeP_Close ENDIF IF nEvent == xbeM_LbClick .and. oXbp:isDerivedFrom( "XbpListBox" ) cFormName := oListBox:getItem( oListBox:getData()[1] ) nText := oListBox:getData()[1] nEvent := xbeP_Close ENDIF IF nEvent == xbeP_Keyboard DO CASE CASE mp1 == xbeK_ESC cString := "ESC" cFormName := "" nText := 0 //oListBox:getData()[1] nEvent := xbeP_Close CASE mp1 == xbeK_RETURN .OR. mp1 == xbeK_F10 cString := "!" cFormName := oListBox:getItem( oListBox:getData()[1] ) nText := oListBox:getData()[1] nEvent := xbeP_Close // CASE mp1 == xbeK_DOWN //.and. oXbp:isDerivedFrom( "XbpListBox" ) // PostAppEvent( xbeP_User ) // CASE mp1 == xbeK_UP //.and. oXbp:isDerivedFrom( "XbpListBox" ) // PostAppEvent( xbeP_User ) ENDCASE ENDIF oXbp:handleEvent( nEvent, mp1, mp2 ) ENDDO oDlgLF:setModalState( XBP_DISP_MODELESS ) // oListBox:destroy() sleep(5) oDlgLF:destroy() // SetAppFocus( oFocus ) RETURN nText //^^ListboxFenster^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FUNCTION DateiStruktur(nA) LOCAL nOldArea := SELECT() LOCAL aStruktur := {}, cText := "" SELECT &nA aStruktur := ASort(DbStruct(),,,{|a1,a2|a1[1]",cVariable)) cVar := SubStr(cVariable,At(">",cVariable)+1,Len(cVariable)-Len(cA)-2) ELSE cA := SubStr(cVariable,1,At("->",cVariable)+1) cVar := SubStr(cVariable,At(">",cVariable)+1,Len(cVariable)-Len(cA)) ENDIF nFLD[1] := &cA->(FieldInfo(&cA->(FieldPos(cVar)),FLD_LEN)) nFLD[2] := &cA->(FieldInfo(&cA->(FieldPos(cVar)),FLD_DEC)) // FieldInfo(FieldPos(SubStr(cVariable,At(">",cVariable)+1,nVarLen-3)),FLD_LEN), ; // FieldInfo(FieldPos(SubStr(cVariable,At(">",cVariable)+1,nVarLen-3)),FLD_DEC) ; RETURN nFLD //gewinnt die genaue Fontbreite aus der GraQueryTextBox FUNCTION FontBreite(cFontName,cFontPt,cBuchstabe) //10.02.2024 16:19 LOCAL nFBreite, oPSb, oFontb, aTextBox, cFont := LTrim(Str(Val(cFontPt)))+"."+cFontName //11.02.2024 13:37 LOCAL oPrinter := XbpPrinter():New() //02.01.2024 12:33 speziell fr KSO LOCAL cDruckerName := IIf(isMEMVAR("cDruckerName").AND.!Empty(cDruckerName),cDruckerName,XbpPrinter():New():Create():devName) //02.01.2024 12:34 fr KSO aMark := {"","","","","",""} //18.03.2024 18:30 DEFAULT cBuchstabe TO " " //10.02.2024 16:19 //18.03.2024 18:31 l”scht die MarkUp-Befehle fr die Berechnung der nFBreite: ^^^^^^^^^^^^^^ DO WHILE ""$cBuchstabe .OR. ""$cBuchstabe .OR. ""$cBuchstabe AEval(aMark,{|x,i|IIf(x$cBuchstabe,cBuchstabe := Stuff(cBuchstabe,At(x,cBuchstabe),Len(x),""),)}) ENDDO //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv oPSb := PrinterPS(cDruckerName) //27.08.2023 cDruckerName LOCAL !! oFontb := XbpFont():new(oPSb) oFontb:CREATE(cFont) GraSetFont(oPSb,oFontb) // aTextBox := GraQueryTextBox(oPSb,Space(10)) //18.09.2023 16:03 Space(10) ist aber identisch mit " " !! IF Len(cBuchstabe)>1 aTextBox := GraQueryTextBox(oPSb,cBuchstabe) //15.02.2024 10:37 in cBuchstabe steckt der Text, dessen Breite gesucht wird ELSE aTextBox := GraQueryTextBox(oPSb,Replicate(cBuchstabe,10)) //10.02.2024 16:22 ENDIF nFBreite := aTextBox[5,1]/100 RETURN nFBreite // in mm, weil 10-Buchstaben-breit in cm !! //06.11.2022 10:37 Suche in offener Auftragsdatei FUNCTION SucheInDatei(nA,cFeld,cInhalt) LOCAL nOldArea := SELECT() LOCAL cAntwort := "nein" LOCAL cAuf := Str(1->auftrnr,6,0) LOCAL nRec PRIVATE cF := cFeld SELECT(nA) nRec := RecNo() DbSuspendNotifications() DbSeek(cAuf,.F.) //13.11.2018 18:48 statt: FIND &cAuf DO WHILE 3->auftrnr=Val(cAuf) .and. .not. eof() IF Upper(cInhalt)$Upper(3->&cF) cAntwort := "ja" ENDIF DbSkip() ENDDO DbGoto(nRec) DbResumeNotifications() SELECT(nOldArea) RETURN cAntwort //12.09.2023 21:17 Prompt abtrennen FUNCTION OhnePrompt(cText,cTrenner) DEFAULT cTrenner TO ":" RETURN AllTrim(SubStr(cText,At(cTrenner,cText)+1)) //02.11.2023 10:54 wofr wird das noch gebraucht??: //28.09.2023 09:40 Seitenumbruch fr weitere Seiten mit Formular FUNCTION NeuesFormular(cHintergrund) DEFAULT cHintergrund TO "" RETURN cHintergrund //02.11.2023 10:50 berechnet width/height des Formulars (==> portrait oder landscape) FUNCTION FormSize(cFormular) LOCAL oBitmap, cXCM, cYcm IF (FExists(cDatver+cFormular) .AND. Upper(Right(cFormular,4))==".PNG") //21.02.2024 13:55 oBitmap := XbpBitmap():new():CREATE(XbpPresSpace():new()) oBitmap:loadFile(cDatver + cFormular) cXCM := IIf(oBitmap:xsize < oBitmap:ysize,"21cm","29.7cm") cYCM := IIf(oBitmap:ysize < oBitmap:xsize,"21cm","29.7cm") ELSE //24.01.2024 19:01 wenn in Inditext~.txt kein Formular eingetragen ist: cXCM := "21cm" cYCM := "29.7cm" ENDIF RETURN {cXCM,cYCM} //02.11.2023 13:20 um CodeBl”cke im inditext einzusparen: vvvvvvvvvvvvvvvvvvvvvvvvvvvvv //02.11.2023 13:26 zum Ankreuzen der richtigen Bestattungsart FUNCTION EFzuX(bestart) RETURN IIf(1->best_art==bestart,"X","") //02.11.2023 13:16 FUNCTION EF_Friedhof() RETURN IIf(!Empty(1->&TO2),1->&TO2,1->&TO4) //02.11.2023 13:16 FUNCTION EF_Wochentag() RETURN IIf(!Empty(oBest:TW2),oBest:TW2,oBest:TW4) //02.11.2023 13:16 FUNCTION EF_Datum() RETURN IIf(!Empty(1->&TD2),1->&TD2,1->&TD4) //02.11.2023 13:16 FUNCTION EF_Uhrzeit() RETURN IIf(!Empty(1->&TZ2),1->&TZ2,1->&TZ4) //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //19.12.2023 18:33 speziell fr Mller/Grnfl„chenamt-Formular // holt sich die Betr„ge zu den Leistungs-Zeilen aus der auftr.dbf FUNCTION GruenBetraege(cFill,nSumZeile) //11.02.2024 18:16 LOCAL nOldArea := SELECT() LOCAL nRec := 3->(RecNo()) DEFAULT cFill TO "_" //11.02.2024 18:16 DEFAULT nSumZeile TO 17 //11.02.2024 18:16 aGruen := AFill(Array(nSumZeile),0) // 16 + Summe - das ist eine PRIVATE von VariPosition_1() SELECT 3 DbSuspendNotifications() DbSetFilter({|| 1->auftrnr == 3->auftrnr }) DbGotop() DO WHILE !Eof() IF 3->neu = "g" // wenn der erste Buchstabe ein kleines g ist nGruen := IIf(Val(3->neu[2])>0 .AND. Val(3->neu[2])<10,Val(3->neu[2]),Asc(3->neu[2])-87) aGruen[nGruen] += 3->betrageu ENDIF DbSkip() ENDDO DbClearFilter() DbGoto(nRec) DbResumeNotifications() SELECT(nOldArea) // AEval( aGruen, {|a,i| a := Str(a,6,2) },,,.T.) cPicture := "@L"+cFill+" 99,999,999.99" AEval( aGruen, {|a,i| aGruen[17]+=a, a := Transform(a,cPicture) },,,.T.) RETURN "" // hilft bei solchen KommaVerbindungen: (UND spart Trim() und Str() und DtoC()) //$(Trim(1->eh_name),1850,130,1610) $(',') $(Trim(1->eh_vname)) $(',') //$(Trim(1->eh_str)) $(',') $(1->eh_ort) //15.11.2023 18:46 FUNCTION AkommaB(aFelder,cF2,cF3,cF4,cF5,cF6,cF7,cF8,cF9,cF10) LOCAL x, cFelder:="" IF ValType(aFelder)=="A" // cF2 == NIL FOR x:=1 TO Len(aFelder) cFelder += IIf(x>1,", ","") cFelder += Trim(aFelder[x]) NEXT ELSE cFelder := TrimVT(aFelder) + ", " + TrimVT(cF2) IF cF3 != NIL cFelder += ", " + TrimVT(cF3) IF cF4 != NIL cFelder += ", " + TrimVT(cF4) IF cF5 != NIL cFelder += ", " + TrimVT(cF5) IF cF6 != NIL cFelder += ", " + TrimVT(cF6) IF cF7 != NIL cFelder += ", " + TrimVT(cF7) IF cF8 != NIL cFelder += ", " + TrimVT(cF8) IF cF9 != NIL cFelder += ", " + TrimVT(cF9) IF cF10 != NIL cFelder += ", " + TrimVT(cF10) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF RETURN cFelder //16.12.2023 09:27 Trim gem„á ValType FUNCTION TrimVT(xVar,nL,nD,cN,cE) LOCAL nPkt := nL // zwischenspeichern von nL LOCAL cVar := nD // wird noch nicht gebraucht... DEFAULT nL TO 0 DEFAULT nD TO 0 DEFAULT cN TO "" IF ValType(xVar)=="C" .AND. Len(xVar)>2 .AND. xVar[1]=="(" .AND. xVar[Len(xVar)]==")" //01.04.2024 19:03 Len cVariable := "TrimVT"+xVar RETURN &cVariable ENDIF IF ValType(xVar)=="C" nL := IIf(ValType(nL)=="C",Val(nL),nL) nD := IIf(ValType(nD)=="C",Val(nD),nD) cN := IIf(ValType(cN)=="C",Val(cN),cN) IF nL==1 // vor dem 1. Leerschritt cVar := SubStr(xVar,1,At(" ",xVar)-1) xVar := cVar ELSEIF nL==2 // nach dem ersten Leerschritt cVar := SubStr(xVar,At(" ",xVar)+1) xVar := cVar ENDIF IF nD>0 // gesperrt um nD Leerschritte cVar := "" FOR n:=1 TO Len(xVar) cVar += xVar[n] + Space(nD) NEXT xVar := cVar ENDIF IF !Empty(cN) IF cN==1 cVar := "" + AllTrim(xVar) + "" ELSEIF cN==2 cVar := "" + AllTrim(xVar) + "" ELSEIF cN==3 cVar := "" + AllTrim(xVar) + "" ELSEIF cN==4 cVar := "" + AllTrim(xVar) + "" ELSEIF cN==5 cVar := "" + AllTrim(xVar) + "" ELSEIF cN==6 cVar := "" + AllTrim(xVar) + "" ELSEIF cN==7 cVar := "" + AllTrim(xVar) + "" ELSE cVar := Trim(xVar) ENDIF ELSE cVar := Trim(xVar) ENDIF ELSEIF ValType(xVar)=="N" // s.o. cVar := Str(xVar) IF "."$cVar .AND. nPkt == NIL //nPkt ist die bergebene nL nPkt := At(".",cVar) //Punkt in der Zahl aber keine nL nL := Len(cVar) nD := nL - nPkt ELSEIF nPkt == NIL //Kein Punkt in der Zahl und keine nL nL := Len(cVar) // dann ist nL die L„nge von cVar nD := 0 ENDIF IF ValType(cE)=="C" cVar := IIf(Len(cN)>0,PadL(LTrim(Str(xVar,nL,nD)),nL,cN)+cE,LTrim(Str(xVar,nL,nD))+cE) ELSE cVar := IIf(Len(cN)>0,PadL(LTrim(Str(xVar,nL,nD)),nL,cN),LTrim(Str(xVar,nL,nD))) ENDIF ELSEIF ValType(xVar)=="D" nD := IIf(ValType(nD)=="N",", ",nD) IF nL==2 cVar := Str(Day(xVar))+". "+CMonth(xVar)+" "+Str(Year(xVar)) ELSEIF nL==3 cVar := CDoW(xVar)+nD+DtoC(xVar) ELSEIF nL==4 cVar := CDoW(xVar)+nD+Str(Day(xVar))+". "+CMonth(xVar)+" "+Str(Year(xVar)) ELSE cVar := DtoC(xVar) ENDIF ENDIF RETURN IIf(ValType(xVar)=="C", cVar,; IIf(ValType(xVar)=="N", cVar,; IIf(ValType(xVar)=="D", cVar,""))) //04.03.2024 13:12 Text fr Trauerkarten FUNCTION Trauerfeier(cTFTag,cTFDat,cTFZeit,cTFOrt, cOrtart) LOCAL cText DEFAULT cTFTag TO AllTrim(1->messetag) DEFAULT cTFDat TO DtoC(1->messedat) DEFAULT cTFZeit TO Str(1->messezeit,5,2) DEFAULT cTFOrt TO AllTrim(1->messewo) DEFAULT cOrtart TO "" //12.03.2024 18:01 cTFTag := AllTrim(cTFTag) cTFDat := IIf(ValType(cTFDat)=="C",cTFDat,DtoC(cTFDat)) cTFZeit := IIf(ValType(cTFZeit)=="C",cTFZeit,Str(cTFZeit,5,2)) cTFOrt := AllTrim(cTFOrt) cOrtart += IIf(Len(cOrtart)>0," ",IIf("St."$cTFOrt .OR. "San"$cTFOrt,"Kirche ","")) //12.03.2024 18:01 RETURN cText := "Die Trauerfeier ist am "+cTFTag+", dem "+cTFDat+", um "+cTFZeit+" Uhr in der "+cOrtart + cTFOrt+"." //==================================================== /** * Parameter nAI, nAE = Area-in, Area-ex z.B. 1, 7 * Parameter cFI, cFE = Filename-in, Filename-ex z.B. BEST, FExBEST * Parameter nAnz = Anzahl der in cFE zu erstellenden gleichen Datens„tze (=Trauerdruck-Stckzahl) * kopiert den aktuellen Datensatz von cFI auf neu erstelltes cFE, so oft, wie es nAnz angibt */ FUNCTION SwapDB(nAI, nAE, cFI, cFE, nAnz) LOCAL nOldArea := SELECT() LOCAL n, aData DEFAULT nAnz TO 1 IF Empty((nAI)->(Alias())) .OR. (nAI)->(Alias()) != Upper(cFI) msgbox(cFI+" ist nicht ge”ffnet in Area "+Str(nAI)) RETURN .F. ENDIF IF (nAE)->(Alias()) == Upper(cFE) // darf eigentlich nicht sein... (nAE)->(DbCloseArea()) ELSEIF Empty((nAE)->(Alias())) (nAI)->(DbCopyStruct("C:\HDBE\"+cFE)) Sleep(100) // fr alle F„lle ... ENDIF (nAE)->(DbUseArea(,,"C:\HDBE\"+cFE,,.F.)) // exclusive SELECT(nAI) aData := Array(FCount()) For n := 1 to FCount() aData[n] := FieldGet( n ) NEXT SELECT(nAE) ZAP // fr alle F„lle DO WHILE nAnz > 0 // erzeugt nAnz Datens„tze APPEND BLANK FOR n := 1 to FCount() FieldPut( n, aData[n] ) NEXT nAnz-- ENDDO (nAE)->(DbCloseArea()) SELECT(nOldArea) RETURN .T. /** 26.02.2024 10:00 * Parameter nAI, cFI z.B. 1, "best" * wenn NIL, dann die Datei in der aktuellen Area * */ FUNCTION FExport(nAI, cFI) LOCAL nOldArea := SELECT() LOCAL aStruktur, aFelder := {} LOCAL cFSTRU LOCAL cFEx, nFE := 17 PRIVATE cI //, cE DEFAULT nAI TO nOldArea DEFAULT cFI TO (nAI)->(Alias()) cFSTRU := "C:\HDBE\FExSTRU_"+cFI+".DBF" IF !FExists( "C:\HDBE\_DB","D" ) //12.11.2024 18:21 RunShell( "/C MD "+"C:\HDBE\_DB",, .T. ) sleep(200) ENDIF cFEx := "C:\HDBE\_DB\FEx_"+cFI+".DBF" // 'NeueDB' als Datenbank einrichten im Verzeichnis C:\HDBE\_DB // fr die offene Datei der Verwaltung in einer 'Struktur'.dbf: // zuerst die Struktur so ver„ndern, dass alle N und D zu C werden: IF !FExists(cFSTRU) (nAI)->(DbCopyExtStruct(cFSTRU)) // erzeugt eine Datei der Strukturdatein von nAI/cFI Sleep(10) // 28.02.2024 15:19 weil DbCreateFrom manchmal aussteigt DbUseArea(.T.,,cFSTRU,"FS",.F.) DO WHILE !FS->(Eof()) // wandelt alle Datens„tze so um, ... IF FS->FIELD_TYPE == "N" FS->FIELD_TYPE := "C" FS->FIELD_DEC := 0 ELSEIF FS->FIELD_TYPE == "D" // ... dass auch N & D zu C werden FS->FIELD_TYPE := "C" FS->FIELD_LEN := 10 ENDIF DbSkip() ENDDO FS->(DbCloseArea()) ELSE SELECT(nFE) ENDIF // aus der 'Struktur'.dbf die šbergabeDatei fr den aktuellen Datensatz kreieren: DbCreateFrom(cFEx,,cFSTRU) aStruktur := (nAI)->(DbStruct()) AEval(aStruktur,{|a|AAdd(aFelder,a[1])}) DbCloseArea() // der Methode SwapInachE nachempfunden: // den aktuellen Datensatz der Verwaltung in die šbergabeDatei kopieren: DbUseArea(.T.,,cFEx,"fe",.F.) fe->(DbAppend()) FOR n:=1 TO Len(aFelder) cI := aFelder[n] // wandelt N und D in C um: (wenn leer, dann fllen mit einem *) DO CASE CASE ValType((nAI)->&cI) == "C" fe->&cI := IIf(Empty((nAI)->&cI),"*",(nAI)->&cI) //27.02.2024 09:44 IIf (Empty... CASE ValType((nAI)->&cI) == "N" IF (nAI)->&cI != Int((nAI)->&cI) // wenn dezimal, dann mit 2 Stellen fe->&cI := IIf(Empty((nAI)->&cI),"*",LTrim(Str((nAI)->&cI,10,2))) ELSE fe->&cI := IIf(Empty((nAI)->&cI),"*",Str((nAI)->&cI)) // Zahl in String verwandeln ENDIF CASE ValType((nAI)->&cI) == "D" fe->&cI := IIf(Empty((nAI)->&cI),"*",DtoC((nAI)->&cI)) // Datum in String verwandeln ENDCASE NEXT fe->(DbSkip()) fe->(DbCloseArea()) SELECT(nOldArea) RETURN .T. //05.01.2024 cPPLinks aus: FExists("C:\HDBE\PdfProgLinks.txt") // speziell fr B~X, weil ein PC keinen AdobeReader kann //18.05.2026 18:57 jetzt eine eigene Funktion: FUNCTION ZeigePDF(cPPLinks, nMaxLines) LOCAL aPPLinks := {}, cPPLinksZ, n IF Len(cPPLinks)>0 FOR n := 1 TO nMaxLines AAdd(aPPLinks, Trim(MemoLine(cPPLinks, 100, n))) NEXT FOR n := 1 TO Len(aPPLinks) cPPLinksZ := aPPLinks[n] // cPPLinksZ ist die erste gefundene AufrufZeile aus dem Text cPPLinks IF FExists(cPPLinksZ) RunShell ("&cFilePDF",cPPLinksZ,.T.) EXIT ENDIF NEXT IIf(n>len(aPPLinks), Alertbox(oCB,"Das PDF-Programm ist nicht ordentlich installiert!",,,"A C H T U N G",3),) ELSE IF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe') //64bit Reader RunShell ("&cFilePDF","C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe",.T.) ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe') //32bit Reader RunShell ("&cFilePDF","C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe",.T.) ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe') // Test nur fr B~X RunShell ("&cFilePDF","C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\AcroRd32.exe",.T.) ELSE Alertbox(oCB,"Der Adobe Reader DC ist nicht ordentlich installiert!",,,"A C H T U N G",3) ENDIF ENDIF RETURN .T.