//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"

//27.11.2023 13:48 ab heute:
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
   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 := 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

// 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 := ;
         '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'+CR+LF+;
         '<HTML>'+CR+LF+;
         '<HEAD>'+CR+LF+;
         '	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">'+CR+LF+;
         '	<TITLE>'+cFile+'</TITLE>'+CR+LF+;
         '	<META NAME="GENERATOR" CONTENT="BEST.EXE">'+CR+LF+;
         '	<META NAME="CHANGEDBY" CONTENT="' + cBuero + '">'+CR+LF+;
         '	<STYLE TYPE="text/css">'+CR+LF+;
         '	<!--'+CR+LF+;
         '		@page { size: 21cm 29.7cm; margin:  ' + cFormSeite + '; }'+CR+LF+;
         '		P { margin-bottom: 0.21cm }'+CR+LF+;
         '		P#cour { font-family: ' + cFont + '; }'+CR+LF+;
         '	-->'+CR+LF+;
         '	</STYLE>'+CR+LF+;
         '</HEAD>'+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
         '<BODY LANG="de-DE" BACKGROUND="'+cFormular+'" DIR="LTR" STYLE="background: url('+cFormular+') no-repeat middle center scroll">',;
         '<BODY LANG="de-DE">')+CR+LF+;
         '<PRE STYLE="margin-top:0;margin-bottom:0">'	//+CR+LF+;
	ELSE
	   cNeuTxt := ;
         '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'+CR+LF+;
         '<HTML>'+CR+LF+;
         '<HEAD>'+CR+LF+;
         '	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">'+CR+LF+;
         '	<TITLE>'+cFile+'</TITLE>'+CR+LF+;
         '	<META NAME="GENERATOR" CONTENT="KSOX.EXE">'+CR+LF+;
         '	<META NAME="CHANGEDBY" CONTENT="' + cBuero + '">'+CR+LF+;
         '	<STYLE TYPE="text/css">'+CR+LF+;
         '	<!--'+CR+LF+;
         '		@page { size: 21cm 29.7cm; margin:  ' + cFormSeite + '; }'+CR+LF+;
         '		P { margin-bottom: 0.21cm }'+CR+LF+;
         '		P#cour { font-family: ' + cFont + '; }'+CR+LF+;
         '		PRE { font-family: ' + cFont + '; font-size: ' + cFSize + '; line-height: ' + LTrim(Str(nZeileMM/10)) + 'cm; }'+CR+LF+;
         '	-->'+CR+LF+;
         '	</STYLE>'+CR+LF+;
         '</HEAD>'+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
         '<BODY LANG="de-DE" STYLE="background: url('+cFormular+') no-repeat middle center scroll">'+CR+LF+;
         '<PRE STYLE="margin-top:0;margin-bottom:0cm">'+CR+LF+;
         '<FONT style=" font-family: ' + cFont + '; font-size: ' + cFSize + '; line-height: ' + LTrim(Str(nZeileMM/10)) + 'cm; ">', ;
         '<BODY LANG="de-DE">'+CR+LF+;
         '<PRE>' )
	ENDIF
	
   cNeuTxt += ConvToAnsiCP(cText)
         
   cNeuTxt += '</FONT></PRE></BODY></HTML>'

	cNeuTxt := StrTran( cNeuTxt, "</B>", "</B>       ")	// 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 )

	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 fr Indiform()
//cOrdner = FormArt-Bezeichnung ohne .txt
//cMail_Adr = Mail-Adresse aus inditext.txt	19.11.2023 11:49
//cMail_Betr = Mail-Betreff aus inditext.txt	19.11.2023 11:49
FUNCTION HTML_Form_01( 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
//09.02.2024 21:54	PRIVATE cBuero						//11.10.2022 16:56 PRIVATE fr VariFunkErsatz_1
	PRIVATE cBetreff := cMail_Betr	//21.11.2023 10:09

   cMail_Body := VariFunkErsatz_1(MemoRead(cDatver+cFormular[1]+"\Body.txt"))	//21.11.2023 09:47

	
   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(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"
	
	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 := ;
         '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'+CR+LF+;
         '<HTML>'+CR+LF+;
         '<HEAD>'+CR+LF+;
         '	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">'+CR+LF+;
         '	<TITLE>'+cFile+'</TITLE>'+CR+LF+;
         '	<META NAME="GENERATOR" CONTENT="KSOX.EXE">'+CR+LF+;
         '	<META NAME="CHANGEDBY" CONTENT="' + cBuero + '">'+CR+LF+;
         '	<STYLE TYPE="text/css">'+CR+LF+;
         '	<!--'+CR+LF+;
         '		@page { size: '+aFormSize[1]+' '+aFormSize[2]+'; margin:  ' + cFormSeite + '; }'+CR+LF+;
         '		P { margin-bottom: 0.21cm }'+CR+LF+;
         '		P#cour { font-family: ' + cFont + '; }'+CR+LF+;
         '	-->'+CR+LF+;
         '	</STYLE>'+CR+LF+;
         '</HEAD>'+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
         '<BODY LANG="de-DE" BACKGROUND="'+cFormular+'" DIR="LTR" STYLE="background: url('+cFormular+') no-repeat middle center scroll">',;
         '<BODY LANG="de-DE">')+CR+LF+;
         '<PRE STYLE="margin-top:0;margin-bottom:0">'	//+CR+LF+;
	ELSEIF !"<INPUT"$Upper(cContainer) 	//27.11.2023 14:31 als Brief, nicht als Formular mit Input
	   cNeuTxt := ;
         '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'+CR+LF+;
         '<HTML>'+CR+LF+;
         '<HEAD>'+CR+LF+;
         '	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">'+CR+LF+;
         '	<TITLE>'+cFile+'</TITLE>'+CR+LF+;
         '	<META NAME="GENERATOR" CONTENT="KSOX.EXE">'+CR+LF+;
         '	<META NAME="CHANGEDBY" CONTENT="' + cBuero + '">'+CR+LF+;
         '	<STYLE TYPE="text/css">'+CR+LF+;
         '		@page { size: 21cm 29.7cm; margin:  ' + cFormSeite + '; }'+CR+LF+;
         '		P { margin-bottom: 0.21cm }'+CR+LF+;
         '		P#cour { font-family: ' + cFont + '; }'+CR+LF+;
         '		PRE { font-family: ' + cFont + '; font-size: ' + cFSize + '; line-height: ' + LTrim(Str(nZeileMM/10)) + 'cm; }'+CR+LF+;
         '	</STYLE>'+CR+LF+;
         '</HEAD>'+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
         '<BODY LANG="de-DE" STYLE="background: url('+cFormular+') no-repeat middle center scroll">'+CR+LF+;
         '<PRE STYLE="margin-top:0;margin-bottom:0cm">'+CR+LF+;
         '<FONT style=" font-family: ' + cFont + '; font-size: ' + cFSize + '; line-height: ' + LTrim(Str(nZeileMM/10)) + 'cm; ">', ;
         '<BODY LANG="de-DE">'+CR+LF+;
         '<PRE>' )
	ELSE
	   cNeuTxt := ;
         '<!DOCTYPE HTML>'+CR+LF+;
         '<HTML LANG="de-DE">'+CR+LF+;
         '<HEAD>'+CR+LF+;
         '	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">'+CR+LF+;
         '	<TITLE>'+cFile+'</TITLE>'+CR+LF+;
         '	<META NAME="GENERATOR" CONTENT="KSOX.EXE">'+CR+LF+;
         '	<META NAME="CHANGEDBY" CONTENT="' + cBuero + '">'+CR+LF+;
         '	<META NAME="VIEWPORT" CONTENT="width=device-width, initial-scale=1.0">'+CR+LF+;
         '	<STYLE TYPE="text/css">'+CR+LF+;
         '		@page { size: '+aFormSize[1]+' '+aFormSize[2]+'; margin:  ' + cFormSeite + '; }}'+CR+LF+;
         '		P { line-height:100%;margin:0; }'+CR+LF+;
         '		P#cour { font-family: ' + cFont + '; }'+CR+LF+;
         '		PRE { font-family: ' + cFont + '; font-size: ' + cFSize + '; line-height: ' + cZeileCM + '; }'+CR+LF+;
			'		DIV { position:absolute; }'+CR+LF+;
			'		FORM { margin:0;padding:0;border:0px; }'+CR+LF+;
         '	</STYLE>'+CR+LF+;
         '</HEAD>'+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
			'<BODY LANG="de-DE" STYLE="min-width:'+aFormSize[1]+';min-height:'+aFormSize[2]+';border:none;padding:0px;margin:0px;">'+CR+LF+;
			'<PRE STYLE="margin:0px;padding:0px;border:none;font-family:'+cFont+';font-size:'+cFSize+';line-height:'+cZeileCM+';">'+CR+LF+;
			'<FORM NAME="Formular" action="mailto:'+cMail_Adr+'?subject='+cMail_Betr+'">'+CR+LF+;		// (body &) attachment geht bei mailto nicht !!
			'<DIV id="Rahmen1" STYLE="position:relative;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;background-color:transparent;">'+CR+LF+;
			'<div style="position:absolute;top:0;left:0;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;background-color:transparent;">'+CR+LF+;
			'<img src="'+cFormular+'" alt="Bild1" style="position:absolute;margin:0px;padding:0px;border:none;width:'+aFormSize[1]+';height:'+aFormSize[2]+';" title="Seite1" /></div>'+CR+LF, ;
			'<BODY LANG="de-DE">'+CR+LF+;
			'<PRE>' )

	ENDIF
//			'<FORM NAME="Formular" action="mailto:adebar@storch.xx?subject=BETREFF&body=BODY&attachment=ANHANG">'+CR+LF+;
//			'<FORM NAME="Formular" action="mailto:'+cMail_Adr+'?subject='+cMail_Betr+'&body='+cMail_Body+'&attachment='+cFilePDF+'">'+CR+LF+;

   cNeuTxt += ConvToAnsiCP(cContainer)
	IF !"<INPUT"$Upper(cContainer) 	//27.11.2023 14:27 als Brief, nicht als Formular mit Input
   	cNeuTxt += '</FONT></PRE></BODY></HTML>'
	ELSE
	   cNeuTxt += '</DIV>'		//24.10.2023 09:52
   	cNeuTxt += '</FORM></PRE></BODY></HTML>'
	ENDIF
	IF !FExists(cFilehtml)
		nHandle := FCreate(cFilehtml)
		FClose(nHandle)
		Sleep(100)
	ENDIF

   nHandle := FCreate(cFilehtml)
   nBytes := FWrite( nHandle, cNeuTxt )
   nBytes := FClose( nHandle )
	sleep(50)
	
	IF AppKeyState(65553)==1 .OR. "INPUT"$Upper(cNeuTxt)	// zusammen mit Strg-Taste	//19.12.2022 15:13 mit LibreOffice zu PDF konvertieren
		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))

      //+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

//		  	IF RunShell (' --headless --convert-to pdf:"writer_pdf_Export:{\"PageRange\":{\"type\":\"string\",\"value\":\"1-\"}}" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
			IF RunShell (' --headless --convert-to pdf:"writer_pdf_Export" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
//		  	IF RunShell (' --headless --convert-to pdf:"writer_pdf_Export:{\"EmbedStandardFonts\":{\"type\":\"boolean\",\"value\":\"true\"},\"PDFUACompliance\":{\"type\":\"boolean\",\"value\":\"true\"}}" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
				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
				
				//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(65552)==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.)
					ELSEIF FExists('C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe')
						RunShell ("&cFilepdf","C:\Program Files (x86)\Microsoft\Edge\Application\msedge.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!!
	IF 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 </HTML> krzen:^
   nHandle := FCreate(cFilehtml)
   nBytes := FWrite( nHandle, cNeuTxt )
   nBytes := FClose( nHandle )
	sleep(50)
			////cFilehtml := Stuff(cFilehtml,At(".html",Upper(cFilehtml)),4,".odt")
//	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	      //+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...
	ELSE 
		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( 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 := ;
         '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'+CR+LF+;
         '<HTML>'+CR+LF+;
         '<HEAD>'+CR+LF+;
         '	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">'+CR+LF+;
         '	<TITLE>'+cFile+'</TITLE>'+CR+LF+;
         '	<META NAME="GENERATOR" CONTENT="KSOX.EXE">'+CR+LF+;
         '	<META NAME="CHANGEDBY" CONTENT="' + cBuero + '">'+CR+LF+;
         '	<STYLE TYPE="text/css">'+CR+LF+;
         '	<!--'+CR+LF+;
         '		@page { size: '+aFormSize[1]+' '+aFormSize[2]+'; margin:  ' + cFormSeite + '; }'+CR+LF+;
         '		P { margin-bottom: 0.21cm }'+CR+LF+;
         '		P#cour { font-family: ' + cFont + '; }'+CR+LF+;
         '	-->'+CR+LF+;
         '	</STYLE>'+CR+LF+;
         '</HEAD>'+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
         '<BODY LANG="de-DE" BACKGROUND="'+cFormular+'" DIR="LTR" STYLE="background: url('+cFormular+') no-repeat middle center scroll">',;
         '<BODY LANG="de-DE">')+CR+LF+;
         '<PRE STYLE="margin-top:0;margin-bottom:0">'	//+CR+LF+;
	ELSEIF !"<INPUT"$Upper(cContainer) 	//27.11.2023 14:31 als Brief, nicht als Formular mit Input
	   cNeuTxt := ;
         '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'+CR+LF+;
         '<HTML>'+CR+LF+;
         '<HEAD>'+CR+LF+;
         '	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">'+CR+LF+;
         '	<TITLE>'+cFile+'</TITLE>'+CR+LF+;
         '	<META NAME="GENERATOR" CONTENT="KSOX.EXE">'+CR+LF+;
         '	<META NAME="CHANGEDBY" CONTENT="' + cBuero + '">'+CR+LF+;
         '	<STYLE TYPE="text/css">'+CR+LF+;
         '		@page { size: 21cm 29.7cm; margin:  ' + cFormSeite + '; }'+CR+LF+;
         '		P { margin-bottom: 0.21cm }'+CR+LF+;
         '		P#cour { font-family: ' + cFont + '; }'+CR+LF+;
         '		PRE { font-family: ' + cFont + '; font-size: ' + cFSize + '; line-height: ' + LTrim(Str(nZeileMM/10)) + 'cm; }'+CR+LF+;
         '	</STYLE>'+CR+LF+;
         '</HEAD>'+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
         '<BODY LANG="de-DE" STYLE="background: url('+cFormular+') no-repeat middle center scroll">'+CR+LF+;
         '<PRE STYLE="margin-top:0;margin-bottom:0cm">'+CR+LF+;
         '<FONT style=" font-family: ' + cFont + '; font-size: ' + cFSize + '; line-height: ' + LTrim(Str(nZeileMM/10)) + 'cm; ">', ;
         '<BODY LANG="de-DE">'+CR+LF+;
         '<PRE>' )
	ELSE
/*         '<HTML LANG="de-DE">'+CR+LF+;*/
	   cNeuTxt := ;
         '<!DOCTYPE HTML>'+CR+LF+;
			'<html lang="de-DE" xml:lang="de-DE" xmlns="http://www.w3.org/1999/xhtml">'+CR+LF+;
         '<HEAD>'+CR+LF+;
         '	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">'+CR+LF+;
         '	<TITLE>'+cFile+'</TITLE>'+CR+LF+;
         '	<META NAME="GENERATOR" CONTENT="KSOX.EXE">'+CR+LF+;
         '	<META NAME="CHANGEDBY" CONTENT="' + cBuero + '">'+CR+LF+;
         '	<META NAME="VIEWPORT" CONTENT="width=device-width, initial-scale=1.0">'+CR+LF+;
         '	<STYLE TYPE="text/css">'+CR+LF+;
         '		@page { size: '+aFormSize[1]+' '+aFormSize[2]+'; margin:  ' + cFormSeite + '; }'+CR+LF+;
         '		P { line-height:100%;margin:0; }'+CR+LF+;
         '		P#cour { font-family: ' + cFont + '; }'+CR+LF+;
         '		PRE { font-family: ' + cFont + '; font-size: ' + cFSize + '; line-height: ' + cZeileCM + '; }'+CR+LF+;
			'		DIV { position:absolute; }'+CR+LF+;
			'		FORM { margin:0;padding:0;border:0px; }'+CR+LF+;
			'		DIV[NAME="Textdiv1"] {border:none !important;background-color:transparent !important;}'+CR+LF+;
			'		INPUT[NAME="Textfeld1"] {border:none !important;background-color:transparent !important;}'+CR+LF+;
			'		::placeholder {color:lightgreen;border:none;}'+CR+LF+;
         '	</STYLE>'+CR+LF+;
         '</HEAD>'+CR+LF+;
         IIf( Upper(Right(cFormular,4))==".PNG", ;
			'<BODY LANG="de-DE" STYLE="min-width:'+aFormSize[1]+';min-height:'+aFormSize[2]+';border:none;padding:0px;margin:0px;">'+CR+LF+;
			'<PRE STYLE="margin:0px;padding:0px;border:none;font-family:'+cFont+';font-size:'+cFSize+';line-height:'+cZeileCM+';">'+CR+LF+;
			'<FORM NAME="Formular" action="mailto:'+cMail_Adr+'?subject='+cMail_Betr+'">'+CR+LF+;		// (body &) attachment geht bei mailto nicht !!
			'<DIV id="Rahmen1" STYLE="position:relative;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;background-color:transparent;">'+CR+LF+;
			'<div style="position:absolute;top:0;left:0;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;background-color:transparent;">'+CR+LF+;
			'<img src="'+cFormular+'" alt="Bild1" style="position:absolute;margin:0px;padding:0px;border:none;width:'+aFormSize[1]+';height:'+aFormSize[2]+';" title="Seite1" /></div>'+CR+LF, ;
			'<BODY LANG="de-DE" STYLE="min-width:'+aFormSize[1]+';min-height:'+aFormSize[2]+';border:none;padding:0px;margin:0px;">'+CR+LF+;
			'<PRE STYLE="margin:0px;padding:0px;border:none;font-family:'+cFont+';font-size:'+cFSize+';line-height:'+cZeileCM+';">'+CR+LF+;
			'<FORM NAME="Formular">'+CR+LF+;		// 21.02.2024 15:10 ohne FORM keine Darstellung von INPUT
			'<DIV id="Rahmen1" STYLE="position:relative;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;background-color:transparent;">'+CR+LF )

//mit Flex:			'<div style="position:absolute;top:0;left:0;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;background-color:transparent;display:flex;justify-content:center;align-items:center;">'+CR+LF+;
//			'<PRE>' )

	ENDIF
//			'<FORM NAME="Formular" action="mailto:adebar@storch.xx?subject=BETREFF&body=BODY&attachment=ANHANG">'+CR+LF+;
//			'<FORM NAME="Formular" action="mailto:'+cMail_Adr+'?subject='+cMail_Betr+'&body='+cMail_Body+'&attachment='+cFilePDF+'">'+CR+LF+;

   cNeuTxt += ConvToAnsiCP(cContainer)
	IF !"<INPUT"$Upper(cContainer) 	//27.11.2023 14:27 als Brief, nicht als Formular mit Input (passiert aber nie!?!?)
   	cNeuTxt += '</FONT></PRE></BODY></HTML>'
	ELSEIF "<FORM"$cNeuTxt	//21.02.2024 15:14	//Upper(Right(cFormular,4))==".PNG"	//24.01.2024 20:50
	   cNeuTxt += '</DIV>'		//24.10.2023 09:52
   	cNeuTxt += '</FORM></PRE></BODY></HTML>'
   ELSE	//24.01.2024 20:49
	   cNeuTxt += '</DIV>'		//21.02.2024 14:04
   	cNeuTxt += '</PRE></BODY></HTML>'
	ENDIF
	IF !FExists(cFilehtml)
		nHandle := FCreate(cFilehtml)
		FClose(nHandle)
		Sleep(100)
	ENDIF
   nHandle := FCreate(cFilehtml)
   nBytes := FWrite( nHandle, cNeuTxt )
   nBytes := FClose( nHandle )
	sleep(50)
	
	IF AppKeyState(65553)==1 .OR. "<INPUT"$Upper(cNeuTxt)	// zusammen mit Strg-Taste	//19.12.2022 15:13 mit LibreOffice zu PDF konvertieren
		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))

      //+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

	//15.03.2025 21:00 wieso klappt die folgende (alte) Zeile als ausfllbare PDF????:
//nur mit LO7:
//		  	IF RunShell (' --headless --convert-to pdf:"writer_pdf_Export:{\"PageRange\":{\"type\":\"string\",\"value\":\"1-\"}}" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
			IF RunShell (' --headless --convert-to "pdf:writer_pdf_Export:{\"ExportFormFields\":{\"type\":\"boolean\",\"value\":\"true\"}}" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
			   RunShell (' --headless --convert-to odt --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
			   cTesthtml := "C:\Users\Kirchner\Documents\Text_Rahmen1.html"
			   RunShell (' --headless --convert-to odt --outdir "&cAuftrOrdner" &cTesthtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
			   cTesthtml := "C:\Users\Kirchner\Documents\Text_Rahmen2.html"
			   RunShell (' --headless --convert-to odt --outdir "&cAuftrOrdner" &cTesthtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
			   cTesthtml := "C:\Users\Kirchner\Documents\Text_Rahmen3.html"
			   RunShell (' --headless --convert-to odt --outdir "&cAuftrOrdner" &cTesthtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.)
//		  	IF RunShell (' --headless --convert-to "pdf:writer_pdf_Export:{\"PageRange\":{\"type\":\"string\",\"value\":\"1-\"}}" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
//15.03.2025 21:00 klappt nicht als ausfllbar			IF RunShell (' --headless --convert-to pdf:"writer_pdf_Export" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
//15.03.2025 21:00 klappt nicht als ausfllbar			IF RunShell (' --headless --convert-to pdf:"writeer_pdf_Export:{\"ExportFormFields\":{\"type\":\"boolean\",\"value\":\"true\"},\"FormsType\":{\"type\":\"long\",\"value\":\"1}"}}" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
				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
				
				//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 !"<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 </HTML> 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
   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)
   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. "<INPUT"$Upper(cNeuTxt)	// zusammen mit Strg-Taste	//19.12.2022 15:13 mit LibreOffice zu PDF konvertieren
		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))

      //+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

	//17.03.2025 09:53	geht mit neueren LOs (24.8.5):
		  	IF RunShell (' --headless --convert-to "pdf:writer_pdf_Export:{\"PageRange\":{\"type\":\"string\",\"value\":\"1-\"}}" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
//geht nicht		  	IF RunShell (' --headless --convert-to pdf:"writer_pdf_Export:{\"PageRange\":{\"type\":\"string\",\"value\":\"1-\"}}" --outdir "&cAuftrOrdner" &cFilehtml', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
//geht nicht			IF RunShell (' --headless --convert-to pdf:"writer_pdf_Export" --outdir "&cAuftrOrdner" &cFileODT', 'C:\Program Files\LibreOffice\program\swriter.exe',.T.) == 0
				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
				
				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 ( "&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 !"<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 </HTML> 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


//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]+".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
	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
	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
	
	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
	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

	IF AppKeyState(65554)==1	// zusammen mit ALT-Taste
	   ? RunShell (" /C START Notepad "+cDatver+cFAV+"inditextF.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 !FExists(cDatver+cFormular) .OR. AppKeyState(65552)==1	// zusammen mit SHIFT-Taste 02.01.2024 12:04
		cFormular := ""				// 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(cFormularPNG)
			cFormularJPG := cFormular
//			cParam := 'C:\Bestatt\KSO\' + 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 (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 &cFAVp &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 &cFAVp &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 "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)
//31.01.2024 15:03		RETURN HTML_Brief(cContainer, cFormular, cFont, cFSize, cFormSeite, cZeileCM, cNotiz_Bez)
		RETURN HTML_Form_1(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_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 AppKeyState(65552)==1	// zusammen mit Shift-Taste	// 17.02.2024 15:45: welchen Sinn hat das??
			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

/*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
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_1(): (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_01( 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,"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/Inditext.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 += '</DIV>'+CR+LF
			cContainer += '<DIV id="'+cRahmID+'"style="position:relative;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;float:left;background-color:transparent;border:0;page-break-before:always;">'+CR+LF
			cContainer += '<div style="position:absolute;top:0;left:0;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;background-color:transparent;">'+CR+LF
			cContainer += '<img src="'+cFormular+'" alt="'+cBildALT+'" align="left" style="position_absolute;margin:0px;padding:0px;border:none;width:'+aFormSize[1]+';height:'+aFormSize[2]+';" title="Seite2ff" />'
			cContainer += '</div>'+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_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!

		//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('</div>',cContainer)			// letztes DIV
		nINP := RAt('" /></div>',cContainer)	// letztes Input
		nTXT := RAt('</textarea></div>',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:
			nDivCM := Len(cVarInhalt+" ")*nFBreite/10	// das was dazukommt in cm (von der n„chsten Variablen)
			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("</div>",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('" /></div>',cContainer), 0, IIf(cVarInhalt[1]==',', cVarInhalt+' ', ' '+cVarInhalt))
		   ELSE
		   	cContainer := Stuff(cContainer,RAt('</textarea></div>',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 += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cZeileCM+';">'
		   	cContainer += '<INPUT TYPE="SUBMIT" VALUE="SENDEN" STYLE="width:3cm;height:'+cInpZeileCM+';" /></div>'+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)
				IF cVarInhalt[1]==">"	//11.02.2024 18:01 rechtsbndig, z.B. Euro
					cVarInhalt := SubStr(cVarInhalt,2)
					cDivCM := LTrim(Str(Len(cVarInhalt+" ")*nFBreite/10))+"cm"
					cLeftCM = LTrim(Str(Val(cLeftCM)-Val(cDivCM)))+"cm"
					cTA := "text-align:right;"
//					cContainer += '<div style="position:absolute;text-align:right;top:'+cTopCM+';left:'+cLeftCM+';width:'+cDivCM+';height:'+cZeileCM+';background-color:rgba(255,255,255,0.01);font-size: '+cETFSize+';font-family:'+cFont+';" >'
				ELSE
					cDivCM := LTrim(Str(Len(cVarInhalt+" ")*nFBreite/10))+"cm"
					cTA := ""
//					// das ist tats„chlich transparent (0.01): background-color:rgba(255,255,255,0.01)
//					cContainer += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cDivCM+';height:'+cZeileCM+';background-color:rgba(255,255,255,0.01);font-size: '+cETFSize+';font-family:'+cFont+';" >'
//X		   	cContainer += '<INPUT TYPE=TEXT NAME="Textfeld1" STYLE="border:none;border-color:transparent;font-family: Consolas, sans-serif; font-size: '+cETFSize+';width:'+cDivCM+';height:'+cZeileCM+' !important;vertical-align:bottom;padding:0px;pointer-events:none;background-color:red;padding-top:5px !important;" value="'+cVarInhalt+'" readonly /></div>'
//X		   	cContainer += '<INPUT TYPE=TEXT NAME="Textfeld1" STYLE="border:none;border-color:transparent;font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cDivCM+';height:'+cInpZeileCM+' !important;background-color:transparent;" readonly value="'+cVarInhalt+'" /></div>'+CR+LF
				ENDIF
				cTAFont := IIf("right"$cTA,"Courier-Bold",cFont)	//12.02.2024 12:39
				// das ist tats„chlich transparent (0.01): background-color:rgba(255,255,255,0.01)
//				cContainer += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cDivCM+';height:'+cZeileCM+';background-color:rgba(255,255,255,0.01);'+cTA+'font-size:'+cETFSize+';font-family:'+cTAFont+' !important;" >'
				cContainer += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cDivCM+';height:'+cZeileCM+';background-color:rgba(255,255,255,0.01);'+cTA+'font:'+cETFSize+' '+cTAFont+' ! important;" >'
		   	cContainer += cVarInhalt+'</div>'+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 += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cTextHoeheCM+';">'
		   	cContainer += '<TEXTAREA TYPE=TEXT NAME="Textfeld1" STYLE="font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cEingabeCM+';height:'+cTextHoeheCM+' !important;overflow:hidden;">'+cVarInhalt+'</textarea></div>'+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
				IF !Empty(cVarInhalt) .AND. cVarInhalt[1]==">"	//11.02.2024 18:01 rechtsbndig, z.B. Euro
					cVarInhalt := SubStr(cVarInhalt,2)
					cDivCM := LTrim(Str(Len(cVarInhalt+" ")*nFBreite/10))+"cm"
					cLeftCM = LTrim(Str(Val(cLeftCM)-Val(cEingabeCM)))+"cm"
					cContainer += '<div style="position:absolute;text-align:right;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cZeileCM+';background-color:rgba(255,255,255,0.01);" >'
					cTA := "text-align:right;"
				ELSE
//				cContainer += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cZeileCM+';padding-bottom:0px;border:none !important;outline:none !important; box-shadow:none !important;">'
					// das ist tats„chlich transparent: background-color:rgba(255,255,255,0.01);
					cContainer += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cZeileCM+';padding-bottom:0px;background-color:rgba(255,255,255,0.01);">'
					cTA := ""
				ENDIF
				IF !Empty(cVarInhalt) .AND. "C"==Upper(cVarInhalt[1]) .AND. "X"==Upper(cVarInhalt[Len(cVarInhalt)])
					check := IIf(cVarInhalt=="X",'checked="checked"',"")
			   	cContainer += '<INPUT TYPE=CHECKBOX NAME="CHECKBOX1" STYLE="font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cZeileCM+';height:'+cZeileCM+' !important;" value="'+cVarInhalt+'" '+check+' /></div>'+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 += '<INPUT TYPE=RADIO NAME="'+cRadioName+'" STYLE="font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cZeileCM+';height:'+cZeileCM+' !important;" value="'+cVarInhalt+'" '+check+' /></div>'+CR+LF
			   ELSE
//			   	cContainer += '<INPUT TYPE=TEXT NAME="Textfeld1" STYLE="position:absolute;bottom:0px !important;padding-bottom:0px !important;font-size: '+cETFSize+';font-family:'+Chr(39)+cFont+Chr(39)+'; width:'+cEingabeCM+';height:'+cInpZeileCM+' !important;border:none !important;outline:none !important; box-shadow:none !important;" value="'+cVarInhalt+'" /></div>'+CR+LF
//			   	cContainer += '<INPUT TYPE=TEXT NAME="Textfeld1" STYLE="position:absolute;bottom:0px !important;padding-bottom:0px !important;font-size: '+cETFSize+';font-family:'+Chr(39)+cFont+Chr(39)+'; width:'+cEingabeCM+';height:'+cInpZeileCM+' !important;border-color:rgba(255,255,255,0.01);background-color:rgba(255,255,255,0.01);" value="'+cVarInhalt+'" /></div>'+CR+LF
					//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)
					ELSE
						cTAFont := cFont
					ENDIF
			   	cContainer += '<INPUT TYPE=TEXT NAME="TextfeldX" STYLE="position:absolute;width:'+cEingabeCM+';height:'+cInpZeileCM+' !important;border-color:rgba(255,255,255,0.01);background-color:rgba(255,255,255,0.71);font-size: '+cETFSize+';font-family:'+cTAFont+';'+cTA+'" value="'+cVarInhalt+'" /></div>'+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 += '</DIV>'
	ENDIF*/
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_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)
			cFS := cFSize		// PRIVATE, damit &cVariable sie verwenden kann
			cFF := cFont
			cVariable := SubStr(cVariable,2,Len(cVariable)-2)		// Font-Berechnung
			xyz := &cVariable
	   	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 += '</DIV>'+CR+LF
			cContainer += '<DIV id="'+cRahmID+'"style="position:relative;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;float:left;background-color:transparent;border:0;page-break-before:always;">'+CR+LF
			cContainer += '<div style="position:absolute;top:0;left:0;width:'+aFormSize[1]+';height:'+aFormSize[2]+';margin:0px;padding:0px;border:none;background-color:transparent;">'+CR+LF
			cContainer += '<img src="'+cFormular+'" alt="'+cBildALT+'" align="left" style="position_absolute;margin:0px;padding:0px;border:none;width:'+aFormSize[1]+';height:'+aFormSize[2]+';" title="Seite2ff" />'
			cContainer += '</div>'+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!

		//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('</div>',cContainer)			// letztes DIV
		nFONT := RAt('</font></div>',cContainer)	//17.02.2024 20:59 letztes FONT im DIV
		nINP := RAt('" /></div>',cContainer)	// letztes Input
		nTXT := RAt('</textarea></div>',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('<div ',cContainer)) .OR. (RAt('text-align:right',cContainer) > RAt('<div ',cContainer))
				nDivCM := FontBreite(cFont,cFSize,cVarInhalt+"W")
//				nDivCM := Len(cVarInhalt+" ")*nFBreite/10	// das was dazukommt in cm (von der n„chsten Variablen)
				nAnf := RAt('width:',cContainer)+6
				nEnd := RAt(';height:',cContainer)-1
				cDivCM := SubStr(cContainer,nAnf,nEnd-nAnf+1)	// die bisherige Breite des Textfeldes
				cDivCM := LTrim(Str(Val(cDivCM)+nDivCM))+"cm"	// ... plus die Breite von der n„chsten Variablen
		   	cContainer := Stuff(cContainer, nAnf, nEnd-nAnf+1, cDivCM)
				//22.02.2024 08:43 zus„tzlich:
				n := IIf(RAt('text-align:center',cContainer) > RAt('<div ',cContainer),2,1)
				nAnf := RAt('left:',cContainer)+5
				nEnd := RAt(';width:',cContainer)-1
				cDivCM := SubStr(cContainer,nAnf,nEnd-nAnf+1)	// die bisherige Breite des Textfeldes
				cDivCM := LTrim(Str(Val(cDivCM)-nDivCM/n))+"cm"	// ... plus die Breite von der n„chsten Variablen
		   	cContainer := Stuff(cContainer, nAnf, nEnd-nAnf+1, cDivCM)
		   ELSE	//29.02.2024 17:46:
				nDivCM := FontBreite(cFont,cFSize,cVarInhalt+"W")
//				nDivCM := Len(cVarInhalt+" ")*nFBreite/10	// das was dazukommt in cm (von der n„chsten Variablen)
				nAnf := RAt('width:',cContainer)+6
				nEnd := RAt(';height:',cContainer)-1
				cDivCM := SubStr(cContainer,nAnf,nEnd-nAnf+1)	// die bisherige Breite des Textfeldes
				cDivCM := LTrim(Str(Val(cDivCM)+nDivCM,5,2))+"cm"	// ... plus die Breite von der n„chsten Variablen
		   	cContainer := Stuff(cContainer, nAnf, nEnd-nAnf+1, cDivCM)
	   	ENDIF
	   	// ... und dann noch der VarInhalt reingestufft werden:
	   	IF nFont > 0 .AND. nFONT < nDIV	//17.02.2024 21:02
		   	cContainer := Stuff(cContainer,RAt("</font></div>",cContainer), 0, IIf(cVarInhalt[1]==",", cVarInhalt, " "+cVarInhalt))
		   ELSE
		   	cContainer := Stuff(cContainer,RAt("</div>",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('" /></div>',cContainer)
				nTA := nEnd-nAnf
				cVarInh := AllTrim(SubStr(cContainer,nAnf,nEnd-nAnf))
				IF RAt('text-align:center',cContainer) > RAt('<div ',cContainer)
					cVarInhalt := PadC(IIf(cVarInhalt[1]==',', cVarInh+cVarInhalt+' ', ' '+cVarInh+' '+cVarInhalt),nTA)
				ELSEIF RAt('text-align:right',cContainer) > RAt('<div ',cContainer)
					cVarInhalt := PadL(IIf(cVarInhalt[1]==',', cVarInh+cVarInhalt+' ', ' '+cVarInh+' '+cVarInhalt),nTA)
				ELSE
					cVarInhalt := IIf(cVarInhalt[1]==',', cVarInh+cVarInhalt+' ', ' '+cVarInh+' '+cVarInhalt)
				ENDIF
		   		cContainer := Stuff(cContainer,RAt('value="',cContainer)+7, RAt('" /></div>',cContainer)-RAt('value="',cContainer)-7, cVarInhalt)
//		   	cContainer := Stuff(cContainer,RAt('" /></div>',cContainer), 0, IIf(cVarInhalt[1]==',', cVarInhalt+' ', ' '+cVarInhalt))
		   ELSE
				cVarInh := AllTrim(SubStr(cContainer,RAt('<textarea>',cContainer)+10,RAt('</textarea>',cContainer)-RAt('<textarea>',cContainer)-10))
		   	cContainer := Stuff(cContainer,RAt('<textarea>',cContainer)+10, RAt('</textarea>',cContainer)-RAt('<textarea>',cContainer)-10, IIf(cVarInhalt[1]==',', cVarInh+cVarInhalt+' ', ' '+cVarInh+cVarInhalt))
//		   	cContainer := Stuff(cContainer,RAt('</textarea></div>',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 += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cZeileCM+';">'
		   	cContainer += '<INPUT TYPE="SUBMIT" VALUE="SENDEN" STYLE="width:3cm;height:'+cInpZeileCM+';" /></div>'+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"
						cDivCM := LTrim(Str(FontBreite(cFont,cFSize,cVarInhalt+Space(Max(1,Len(cVarInhalt)/10))),5,2))+"cm"
					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 += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cDivCM+';height:'+cZeileCM+';background-color:rgba(255,255,255,0.01);border:1px solid rgba(255,255,255,0.01);'+cTA+'font-size:'+cETFSize+';font-family:'+cTAFont+';" >'
		   	IF cAusfuell == "HTML"	//18.02.2024 10:51 ausfllen mit LO, daher <FONT>

//					IF !Empty(cVarInhalt) .AND. "C"==Upper(cVarInhalt[1]) .AND. "X"==Upper(cVarInhalt[Len(cVarInhalt)])
//						check := IIf(cVarInhalt=="X",'checked="checked"',"")
//				   	cContainer += '<INPUT TYPE=CHECKBOX NAME="CHECKBOX1" STYLE="font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cZeileCM+';height:'+cZeileCM+' !important;" value="'+cVarInhalt+'" '+check+' /></div>'+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 += '<INPUT TYPE=RADIO NAME="'+cRadioName+'" STYLE="font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cZeileCM+';height:'+cZeileCM+' !important;" value="'+cVarInhalt+'" '+check+' /></div>'+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 <FONT size=>
				   	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
						IF Val(cFS) < 8 .AND. Len(cFS) == 1 
					   	cContainer += '<font size='+cFS+' face='+cFF+'>'+cVarInhalt+'</font></div>'+CR+LF
					   ELSE
					   	cContainer += '<font size='+aTFSize[Val(cFS)+1]+' face="'+cFF+'">'+cVarInhalt+'</font></div>'+CR+LF
					   ENDIF
			   ELSE
			   	cContainer += cVarInhalt+'</div>'+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	// <textarea> == IMMER PDF
				cTopCM := LTrim(Str(aPosition[2]/100+Val(cZeileCM)-Val(cTextHoeheCM)))+"cm"
				cLeftCM := LTrim(Str(aPosition[1]/100))+"cm"
				cContainer += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cTextHoeheCM+';">'
		   	cContainer += '<TEXTAREA TYPE=TEXT NAME="Textfeld1" STYLE="font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cEingabeCM+';height:'+cTextHoeheCM+' !important;overflow:hidden;">'+cVarInhalt+'</textarea></div>'+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							// <input> == 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 += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cZeileCM+';'+cTA+'background-color:rgba(255,255,255,0.01);" >'
				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 += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cZeileCM+';'+cTA+'background-color:rgba(255,255,255,0.01);" >'
				ELSE
					// das ist tats„chlich transparent: background-color:rgba(255,255,255,0.01);
					cTA := ""
	//				cContainer += '<div style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cZeileCM+';'+cTA+'padding-bottom:0px;background-color:rgba(255,255,255,0.01);">'
					cContainer += '<div name="Textdiv1" style="position:absolute;top:'+cTopCM+';left:'+cLeftCM+';width:'+cEingabeCM+';height:'+cZeileCM+';'+cTA+'padding-bottom:0px;background-color:rgba(255,255,255,0.01);border:none !important;">'	//24.03.2025 11:03 statt Vorzeile
				ENDIF
				IF !Empty(cVarInhalt) .AND. "C"==Upper(cVarInhalt[1]) .AND. "X"==Upper(cVarInhalt[Len(cVarInhalt)])
					check := IIf(cVarInhalt=="X",'checked="checked"',"")
			   	cContainer += '<INPUT TYPE=CHECKBOX NAME="CHECKBOX1" STYLE="font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cZeileCM+';height:'+cZeileCM+' !important;" value="'+cVarInhalt+'" '+check+' /></div>'+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 += '<INPUT TYPE=RADIO NAME="'+cRadioName+'" STYLE="font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cZeileCM+';height:'+cZeileCM+' !important;" value="'+cVarInhalt+'" '+check+' /></div>'+CR+LF
			   	cContainer += '<INPUT TYPE=RADIO NAME="'+cRadioName+'" STYLE="appearance:checkbox;font-size: '+cETFSize+';font-family:'+cFont+'; width:'+cZeileCM+';height:'+cZeileCM+' !important;" value="'+cVarInhalt+'" '+check+' /></div>'+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 += '<INPUT TYPE=TEXT NAME="Textfeld1" STYLE="margin:0.01cm;padding:0.01cm;width:'+cEingabeCM+';height:'+cInpZeileCM+' !important;border:none !important;font-size:'+cETFSize+';font-family:'+cTAFont+';'+cTA+'" value="'+cVarInhalt+'" /></div>'+CR+LF	//24.03.2025 11:03 statt n„chster Zeile
	//				cContainer += '<INPUT TYPE=TEXT NAME="Textfeld1" STYLE="position:absolute;display:inline-block;margin:auto;width:'+cEingabeCM+';height:'+cInpZeileCM+' !important;border-color:rgba(255,255,255,0.01);background-color:rgba(255,255,255,0.71);font-size: '+cETFSize+';font-family:'+cTAFont+';'+cTA+'" value="'+cVarInhalt+'" /></div>'+CR+LF
				//			cContainer += '<INPUT TYPE=TEXT NAME="Textfeld1" STYLE="position:absolute;width:'+cEingabeCM+';height:'+cInpZeileCM+' !important;border-color:rgba(255,255,255,0.01);background-color:rgba(255,255,255,0.71);font-size: '+cETFSize+';font-family:'+cTAFont+';'+cTA+'" value="'+cVarInhalt+'" /></div>'+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 += '</DIV>'
	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 eine Formularart aus !   -   (nur Formular mit STRG-Taste, nur Inhalt mit SHIFT-Taste, Editieren mit ALT-Taste)"
   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_LbDown
//   		nText := oXbp:cargo
//			ENDIF

      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_User
//         cFormName := oListBox:getItem( oListBox:getData()[1] )
//         nText := oListBox:getData()[1]
//      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]<a2[1]})
	FOR i := 1 TO Len(aStruktur)
		aFeld := aStruktur[i]
		cText += PadR(aFeld[1],12) + ", " + PadR(aFeld[2],4) + ", " + PadR(Str(aFeld[3],2,0),4) + ", " + PadR(Str(aFeld[4],2,0),4) + ";     "
	NEXT
	SELECT(nOldArea)
RETURN cTEXT


// 28.03.2023 19:00 holt in der richtigen Area FLD_LEN und FLD_DEC
FUNCTION F_Info(cVariable)
	LOCAL nFLD := Array(2)
	IF cVariable[1] == "("
		cA := SubStr(cVariable,2,At("->",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 := {"<b>","<u>","<i>","</b>","</u>","</i>"}	//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 "<b>"$cBuchstabe .OR. "<u>"$cBuchstabe .OR. "<i>"$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 := "<b>" + AllTrim(xVar) + "</b>"
			ELSEIF cN==2
				cVar := "<u>" + AllTrim(xVar) + "</u>"
			ELSEIF cN==3
				cVar := "<b><u>" + AllTrim(xVar) + "</u></b>"
			ELSEIF cN==4
				cVar := "<i>" + AllTrim(xVar) + "</i>"
			ELSEIF cN==5
				cVar := "<b><i>" + AllTrim(xVar) + "</i></b>"
			ELSEIF cN==6
				cVar := "<u><i>" + AllTrim(xVar) + "</i></u>"
			ELSEIF cN==7
				cVar := "<b><u><i>" + AllTrim(xVar) + "</i></u></b>"
			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.
	