//FormHtml_2.prg 26.08.2023 18:40 //Sammlung der Funktionen fr die indiText/indiForm // sammelt die Kern-Inditext-Funktionen aus KSOX fr den Formulardruck per HTML und OpenOffice-Writer // die kleineren Funktionen sind inzwischen meist in Form_Html_1 (fr KSOX UND die anderen Bestatter) #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" //27.11.2023 13:48 ab heute: FUNCTION HTML_Brief_2( 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 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_2() PRIVATE cBuero //11.10.2022 16:56 PRIVATE fr VariFunkErsatz 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 := 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 ) cBuffer := Space(3000) nBytes := FRead( nHandle, @cBuffer, 3000 ) 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 // vermutlich hier berflssig, weil schon in Inditext_2() 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
	   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 += '
' 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," ") ) nBytes := FClose( nHandle ) IF AppKeyState(65553)==1 .OR. "INPUT"$cNeuTxt // zusammen mit Strg-Taste //19.12.2022 15:13 mit LibreOffice zu PDF konvertieren //geht nicht IF RunShell (' /C START C:\HDBE\swriter.libre.lnk --headless --convert-to pdf:"writer_pdf_Export" C:\HDBE\HTML_Brief.html',cComCom,.T.) //geht nicht IF RunShell (" /C START C:\Progra~1\LibreOffice\program\swriter.exe --headless --convert-to pdf:'writer_pdf_Export' C:\HDBE\HTML_Brief.html",cComCom,.T.) // so nicht! komplette Pfadangabe statt Link IF RunShell (' --headless --convert-to pdf:"writer_pdf_Export" --outdir "C:\HDBE" C:\HDBE\HTML_Brief.html', 'C:\HDBE\swriter.libre.lnk',.T.) == 0 IF FExists('C:\Program Files\LibreOffice\program\swriter.exe') dHeute := DATE() //02.01.2023 13:03 cSZeit := Time() //30.12.2022 15:36 nSZeit := Val(SubStr(cSZeit,1,2))*3600 + Val(SubStr(cSZeit,4,2))*60 + Val(SubStr(cSZeit,7,2)) IF RunShell (' --headless --convert-to pdf:"writer_pdf_Export" --outdir "C:\HDBE" C:\HDBE\HTML_Brief.html', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0 // geht mit OpenOffice nicht! IF RunShell (' -headless -convert-to pdf:"writer_pdf_Export" C:\HDBE\HTML_Brief.html', 'C:\Program Files (x86)\OpenOffice 4\program\swriter.exe',.T.) //30.12.2022 15:36 statt sleep(300): dFDatum := Directory("C:\HDBE\HTML_Brief.pdf")[1,F_WRITE_DATE] //02.01.2023 13:03 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 := 0 DO WHILE (nSZeit > 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 IF nZ > 20 msgbox("Achtung: Die PDF-DAtei ist vermutlich von einem frheren Fall!") ELSEIF FExists('C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe') RunShell (' /N C:\HDBE\HTML_Brief.pdf','C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe',.T.) ELSEIF FExists('C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe') RunShell (' /N C:\HDBE\HTML_Brief.pdf','C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe',.T.) ELSE msgbox("Der Adobe Reader DC ist nicht ordentlich installiert!") 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. //aus FUNCTION HTML_Brief_2 fr Indiform() //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_2( 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" 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 //08.01.2024 10:45 in inditext_1() PRIVATE cBuero //11.10.2022 16:56 PRIVATE fr VariFunkErsatz PRIVATE cBetreff := cMail_Betr //21.11.2023 10:09 cMail_Body := IIf(Empty(cFormular),"",VariFunkErsatz_2(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
	   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+; '
' )

	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
				
				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
		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 !Upper(AppName())$"KSOX.EXE" .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 !"INPUT"$Upper(cNeuTxt)
			dHeute := DATE()		//02.01.2023 13:03
			cSZeit := Time()		//30.12.2022 15:36
			nSZeit := Val(SubStr(cSZeit,1,2))*3600 + Val(SubStr(cSZeit,4,2))*60 + Val(SubStr(cSZeit,7,2))

	//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
		//	//27.11.2023 18:39 die gerade im Writer ge„nderte HTML-Datei bis auf  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.

//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_2 im Text einsetzen
//						den Text ber HTML_Brief_2 ausdrucken
FUNCTION Inditext_2(oDlg1,cFAV)		//12.09.2023 11:31 cFAV Fall/Adressen/Versicherung (identifiziert den Knopf F\ A\ V\)
	LOCAL cTexte := MemoRead(cDatver+cFAV+"InditextF.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 := "Oberhausen"	//11.10.2022 16:56 PRIVATE fr VariFunkErsatz/VariPosition
	PRIVATE cRufnummer := "0208 631349"	//11.10.2022 16:56 PRIVATE fr VariFunkErsatz/VariPosition
	PRIVATE cHeute := DtoC(DATE())
	
	// nur fr KSOX gedacht, daher ja auch inditext_2 !!
   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
	
	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 inditextF.txt 
	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]

	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 wenn 5->VERSKZ statt cMail_Adr in der inditextF.txt steht: 
	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+"inditextF.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.
	ELSEIF AppKeyState(65552)==1	// zusammen mit SHIFT-Taste 02.01.2024 12:04
		cFormular := ""				// ohne Hintergrund ausdrucken (z.B. ohne Briefbogen)
	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(cFormularPNG)
			cFormularJPG := cFormular
			cParam := 'C:\Bestatt\KSO\' + cFormularJPG + ' /convert=' + Substr(cFormularPNG,3)
//			xyz := RunShell (' --headless --convert-to png --outdir "F" &cFormularJPG', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
			xyz := RunShell (' &cParam', 'C:\Program Files (x86)\IrfanView\i_view32.exe',.T.)
			msgbox(cFormularJPG + " 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
//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
//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(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
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	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 Upper(AppName())$"KSOX.EXE" .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 Val(cZeileCM) == 0
			cContainer := VariErsatz(cFileInhalt)	// in cFile steckt jetzt der komplette Text (nicht nur der Filename!)
		ELSE
			cFile := 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)
//31.01.2024 15:03		RETURN HTML_Brief(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez)
		RETURN HTML_Form_2(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez," ", cFile)	//31.01.2024 15:03
	ELSE // wenn Len(aPosition)>=3 auch fr KSOX!
	// fr alle Bestatter	
		IF Val(cZeileCM) == 0
			cContainer := VariFunkErsatz_2(cFileInhalt)	// in cFileInhalt steckt jetzt der komplette Text (nicht nur der Filename!)
		ELSE
			cFileInhalt := VariPosition_2(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_2() alle Variablen im Text positioniert bergeben.
		ENDIF
		IF AppKeyState(65552)==1	// zusammen mit Shift-Taste
			RETURN HTML_Brief_2(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez)
		ELSE
			RETURN HTML_Form_2(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



/*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, weil ohne Funk es bereits in AAA existierte
FUNCTION VariFunkErsatz_2( cString)	//08.01.2024 09:54 als _2 umbenannt - wird allerdings garnicht gebraucht (z.Zt.)
   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_2 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() */
					                                      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.*/
FUNCTION VariPosition_2( 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 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
   PRIVATE cVariable, nSp := 0	//03.09.2023 13:42 fr die id der SPANs 
	PRIVATE aGruen 			//19.12.2023 18:57 speziell fr Mllers Grnfl„chenFormular

   DEFAULT cContainer TO ""

	nFBreite := FontBreite(cFont,cFSize)	//28.12.2022 14:26 Buchstabenbreite aus aTextBox ausgerechnet
	nInpFBreite := FontBreite(cFont,"11pt")	//28.11.2023 16:18
	
	// 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))
   //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

	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.
			      
      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("}",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 einen 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)
				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 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() */ 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! //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" 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 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 //23.01.2024 dazu muss die width des DIVs vergr”áert werden: nDivCM := Len(cVarInhalt+" ")*nFBreite/10 // das was dazukommt in cm nAnf := RAt('width:',cContainer)+6 nEnd := RAt(';height:',cContainer)-1 cDivCM := SubStr(cContainer,nAnf,nEnd-nAnf+1) cDivCM := LTrim(Str(Val(cDivCM)+nDivCM))+"cm" cContainer := Stuff(cContainer, nAnf, nEnd-nAnf+1, cDivCM) // ... und dann noch der VarInhalt reingestufft werden: cContainer := Stuff(cContainer,RAt("",cContainer), 0, IIf(cVarInhalt[1]==",", cVarInhalt, " "+cVarInhalt)) aPos[1] += Len(cVarInhalt) * nFBreite * 10 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 cContainer := Stuff(cContainer,RAt('" />',cContainer), 0, IIf(cVarInhalt[1]==',', cVarInhalt+' ', ' '+cVarInhalt)) ELSE cContainer := Stuff(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 // keine Eingabe-L„nge, wieso also INPUT ??? (immerhin readonly) cDivCM := LTrim(Str(Len(cVarInhalt)*nFBreite/10))+"cm" cContainer += '
' //cContainer += '
' // cContainer += ''+CR+LF cContainer += cVarInhalt+''+CR+LF //24.09.2023 12:14 berschreibt fr Inputfelder: aPos[1] := aPosition[1] + Len(cVarInhalt)*nFBreite*10 aPos[2]=aPosition[2] ELSEIF Val(cTextHoeheCM) > 0 cTopCM := LTrim(Str(aPosition[2]/100+Val(cZeileCM)-Val(cTextHoeheCM)))+"cm" cLeftCM := LTrim(Str(aPosition[1]/100))+"cm" cContainer += '
' cContainer += '
'+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 // cContainer += '
' cContainer += '
' 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 // cContainer += ''+CR+LF // cContainer += ''+CR+LF 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) ENDDO /* IF nSO > 0 cContainer += '' ENDIF*/ RETURN cString