🙏 Helfen Sie jetzt mit, unser LibreOffice Forum zu erhalten! 🙏
Mit Ihrer Spende sichern Sie den Fortbestand, den Ausbau und die laufenden Kosten dieses Forums. 🌱

🍀 Jeder Beitrag zählt – vielen Dank für Ihre Unterstützung!🍀

❤️ DANKE >> << DANKE ❤️

>> Dank Ihrer Unterstützung -> Keine Werbung für alle registrierten LibreOffice-Forum User! <<
🤗 Als Dankeschön werden Sie im Forum als LO-SUPPORTER gekennzeichnet. 🤗

gelöst; variable Zellenzahl ermitteln

Alles zur Programmierung im LibreOffice.
craig
* LO-Experte *
Beiträge: 1137
Registriert: Do 21. Apr 2016, 11:42

Re: variable Zellenzahl ermitteln

Beitrag von craig » Sa 6. Feb 2021, 18:34

Hallo Natal,

nur keine Panik.

Die Meldung "Geschlossen" entstammt der Fehlerroutine im Makro.
Wenn die CSV-Datei bereits geöffnet wird, darf die CSV-Datei
nicht noch einmal per Makro geöffnet werden.

Deshalb wird die CSV-Datei vom Makro aus geschlossen, aber nicht gespeichert!
Jetzt ist das Programm bereit für einen Neuanfang.

Der Reihe nach:
  1. Kommt es zu der Meldung (Im neuen Makro)
    "Die CSV-Datei 'Hans_Meerkatz*.CSV' ist bereits geöffnet und wird nun geschlossen!"
    , dann wird die CSV-Datei ungespeichert geschlossen.
  2. Du siehst in Calc nun eine unbearbeitet oder teilbearbeitete
    Datei (Unbenannt xxx) dies kannst Du schließen ohne zu speichern
  3. Fange nochmal von vorn an:
    Menü Datei → Dokumentvorlagen → Dokumentvorlage verwalten...
  4. Jetzt läuft das Makro wieder ohne Aufruf der Fehlerroutine.
Daraus folgt:
Wenn Du die CSV-Datei zur Bearbeitung geöffnet hast, dann
musst Du die CSV-Datei erst schließen, um das Makro zu starten.

Ich hätte die Fehlermeldung etwas ausführlicher gestalten sollen.
Deshalb hier eine geänderte Makro-Version:

Code: Alles auswählen

REM  *****  BASIC  *****
Option Explicit

Dim oDocCSV as Object  

REM modCSVImport
Sub [CSV_DATEN importieren]
Dim oDocAusVorlage as Object

Dim oAllComponents as Object
Dim oElements as Object
Dim oElement as Object

Dim oSheetAusVorlage as Object
Dim oRange1AusVorlage as Object
Dim oRange2AusVorlage as Object
Dim oRange3AusVorlage as Object

Dim oSheet as Object
Dim oRange1 as Object
Dim oRange2 as Object
Dim oRange3 as Object
Dim oRange4 as Object

Dim oCellCursor as Object

Dim fSekunde as Double
Dim fTime as Double

Dim nEndRow1 as Long
Dim nEndRow2 as Long

Dim nCnt1 as Long
Dim nCnt2 as Long
Dim nCnt3 as Long

Dim mData1() as Variant	' Array für die Daten
Dim mData2() as Variant	' Array für die Daten
Dim mData3() as Variant	' Array für die Daten

Dim sFileCSV as String
Dim sPath as String
Dim sFile as String
Dim sUrl as String

Dim bFound as Boolean

	oDocAusVorlage=ThisComponent

		oSheetAusVorlage=oDocAusVorlage.CurrentController.ActiveSheet
			oRange1AusVorlage=oSheetAusVorlage.getCellRangeByName("A2:C2")
			oRange2AusVorlage=oSheetAusVorlage.getCellRangeByName("A4:C86410")
REM ---------------------------------------------------------------------------
REM 				Zellinhalte löschen
REM
REM VALUE		Nummerische Werte
REM DATETIME	Datum/Zeit-Werte
REM STRING		Text
REM ANNOTATION	Die Notiz
REM FORMULA		Formeln
REM HARDATTR	Die harten Formatierungen
REM STYLES		Styles
REM OBJECTS		Grafik
REM EDITATTR	Textformartierungen ?
			oRange1AusVorlage.ClearContents(com.sun.star.sheet.CellFlags.VALUE _
                         + com.sun.star.sheet.CellFlags.STRING _
                         + com.sun.star.sheet.CellFlags.DATETIME)
                         
			oRange2AusVorlage.ClearContents(com.sun.star.sheet.CellFlags.VALUE _
                         + com.sun.star.sheet.CellFlags.STRING _
                         + com.sun.star.sheet.CellFlags.DATETIME)
                         

REM ══════════════════════════════════════════════════════════════════════════════════════════════════════
REM 				Hier die Pfadangabe, bzw. die URL ändern

	' Unter Linux auch als URL angeben
	sUrl="file:///home/servus/Schreibtisch/Ha/" 
		sFile=dir(sUrl & "Hans*.csv")
			sPath = convertFromUrl(sUrl) & sFile

	
REM ══════════════════════════════════════════════════════════════════════════════════════════════════════

REM 			...................................
REM Prüfen ob die CSV-Datei bereits geöffnet ist
	sURL = ConverttoURL(sPath)
	bFound=False
		oAllComponents = StarDesktop.getComponents	
			oElements = oAllComponents.CreateEnumeration
	Do While oElements.HasMoreElements
		oElement = oElements.NextElement
		If oElement.hasLocation Then
			If oElement.URL = sUrl Then
					bFound = True
					 Goto ErrorHandler
				Exit Do
			End If	
		End If
	Loop
	
REM -----------------------------------------------------------------------------------------------------
REM Prüfung ob die Datei existiert.
REM Dazu wird die "FileExists(sUrl)" aufgerufen;
REM "FileExists(sUrl)" = TRUE		' Datei existiert
REM "FileExists(sUrl)" = FALSE		' Datei existiert nicht oder der Dateiname ist falsch, bzw.
REM der Dateiname entspricht nicht den Vorgaben, welche von diesem Makro gefordert werden
	If FileExists(sUrl) Then
		' "FileExists(sUrl)" = TRUE
'		msgBox surl
	Else
		' "FileExists(sUrl)" = FALSE
    	msgBox "Die angegebene Datei:" & chr(10) & _
     			sFileCSV	 & chr(10) & _
     			"exisitiert nicht!"  & chr(10) & _
     		"--------------------------------"  & chr(10) & _
     		"Das Programm wird beendet"	,16, "Datei nicht vorhanden"
     			Exit Sub
  End If 

REM 			...................................
REM CSV-Datei öffnen
    sFileCSV = convertToUrl(sPath)
    if len(sFileCSV)>0 then
        dim mFileProps(2) as new com.sun.star.beans.PropertyValue
        mFileProps(0).Name = "FilterName" 	: mFileProps(0).Value = "Text - txt - csv (StarCalc)"
		' der erste Token (59) der Filteroptionen gibt den Datenfeld-Separator an:
		' Kommata	= 44
		' Semikola	= 59
        mFileProps(1).Name = "FilterOptions" : mFileProps(1).Value = "44,34,76,1,,0,false,true,true,false"
		' Datei im Hintergrund öffnen
        mFileProps(2).Name = "Hidden"		: mFileProps(2).Value = True
        oDocCSV = StarDesktop.loadComponentFromURL(sFileCSV, "_blank", 0, mFileProps())        
    end if

REM 			...................................
REM Daten aus dem CSV-File kopieren

	oSheet=oDocCSV.CurrentController.ActiveSheet

REM ----------------------------------------------------------------------------------------------------------------------------------------------
			' CSV-Datei:	letzte befüllte Zelle
			oCellCursor = oSheet.createCursor()
	   			oCellCursor.GotoEndOfUsedArea(True)
					nEndRow1 = oCellCursor.getRangeAddress.EndRow+1
	
		' CSV-Datei: Zellbereich "C2:E2"
		oRange1=oSheet.getCellRangeByName("C2:E2")					' CSV-Daten kopieren
		
			' CSV-Datei: Zellbereich "B4:C (letzte Zeile)"
REM getCellRangeByPosition ( nLeft as long, nTop as long, nRight as long, nBottom as long )
			oRange2=oSheet.getCellRangeByPosition(1,3,2,nEndRow1)
			' Leeres Array dimensionieren aus Spalte "AX" und "AZ"
			oRange3=oSheet.getCellRangeByPosition(49,3,50,nEndRow1)

REM ----------------------------------------------------------------------------------------------------------------------------------------------
			mData1()=oRange1.getDataArray()	' CSV-Datei: Daten aus Zellebereich "C2:E2"
			mData2()=oRange2.getDataArray()	' CSV-Datei: Daten aus Spalte "B" und "C"
			mData3()=oRange3.getDataArray()	' CSV-Datei: Daten aus Spalte "AX" und "AZ" (Daten = "")

REM ----------------------------------------------------------------------------------------------------------------------------------------------
REM				CSV-Daten aus Array in neues Dokument schreiben
		oSheetAusVorlage.getCellRangeByName("A2:C2").setDataArray(mData1())
		oSheetAusVorlage.getCellRangeByPosition(2,3,3,nEndRow1).setDataArray(mData2())
	

REM neues Dokument: Inhalt "B2" kopieren und in  Zelle "B4" schreiben
		oSheetAusVorlage.getCellRangeByName("B4").Value=	oSheetAusVorlage.getCellRangeByName("B2").Value

REM ----------------------------------------------------------------------------------------------------------------------------------------------
REM Zähler für Spalte A

			' neues Dokument: letzte befüllte Zelle
			oCellCursor = oSheetAusVorlage.createCursor()
	   			oCellCursor.GotoEndOfUsedArea(True)
					nEndRow2 = oCellCursor.getRangeAddress.EndRow+1 

fSekunde=oSheetAusVorlage.getCellRangeByName("B4").Value
fTime=oSheetAusVorlage.getCellRangeByName("B4").Value
nCnt2=1	' Initialisierung: Zähler für Spalte "A"
nCnt3=0
Dim nUB as Long
nUB=uBound(mData3())
			mData3(0)(1)=oSheetAusVorlage.getCellRangeByName("$B$2").Value
			For nCnt1=1 To nEndRow1
						If nCnt3 >nUB Then Exit For
					If mData2(nCnt3)(0) = ""  OR mData2(nCnt3)(1) = "" Then
							' DANN Arrayfeld = ""
							mData3(nCnt3)(0)=""
							mData3(nCnt3)(1)=""
							nCnt3=nCnt3+1
					' WENN nicht LEER, 
					ElseIf mData2(nCnt3,0) >= 0 AND mData2(nCnt3,1) >= 0 Then
						' Wen Zähler > uBound(mData3())
						If nCnt3 >nUB Then Exit For
							' DANN Spalte "A" inkrementieren
							mData3(nCnt3)(0) = nCnt2
							If nCnt1 = 1 Then
								mData3(nCnt3)(1) = fTime+fSekunde					' Zeit für Zelle B5
							Else
								mData3(nCnt3)(1) = fTime+mData2(nCnt3)(0) 		'Zeitberechnung bis letzte Zeile
							End IF
								' Zähler inkrementieren
								nCnt2=nCnt2+1
								nCnt3=nCnt3+1
					End If
				Next nCnt1
		

			mData3(0)(1)=oSheetAusVorlage.getCellRangeByName("$B$2").Value

'			oSheetAusVorlage.getCellRangeByName("$A$4:$B$23").setDataArray(mData3())
			oSheetAusVorlage.getCellRangeByPosition(0,3,1,nEndRow1).setDataArray(mData3())

REM ----------------------------------------------------------------------------------------------------------------------------------------------
REM Zellen formatieren mit Formatcode 41 = HH:MM:SS  → 12:12:10
REM https://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1i18n_1_1NumberFormatIndex.html
		oSheetAusVorlage.getCellRangeByName("B2:C2").NumberFormat=41
'		oSheetAusVorlage.getCellRangeByName("B4").NumberFormat=41
		oSheetAusVorlage.getCellRangeByName("B4:C86410").NumberFormat=41
REM 			...................................
REM CSV-Datei schließen
	oDocCSV.Close(True)
		Msgbox "Programmende:  'Sub [CSV_DATEN importieren]'"  & Chr(10) & _
				    		"______________________________" & Chr(10)  & Chr(10) & _
				    		"Es wurden " & nCnt3 & " Datensätze geschrieben.", 64,"Programmende"
REM End If

Exit Sub

REM 			...................................
ErrorHandler:

    Reset

	    MsgBox "Die CSV-Datei"  & Chr(10) & _
	    			sPath   & Chr(10) & _
	    			 "ist bereits geöffnet" & Chr(10) & _
	    			   "Bitte schließen Sie die Datei und starten das Programm erneut" & Chr(10) & _
	    		"______________________________" & Chr(10)  & Chr(10) & _
			   	"Das Programm wird beendet!"	,0,"Fehlermeldung"
REM CSV-Datei schließen
XClose
End Sub

Sub XClose
dim i As Integer
dim ncnt1
dim z
dim y
REM CSV-Datei schließen
'xray 
nCnt1=Stardesktop.Frames.Count
		for i = 0 to nCnt1-1
			z=Stardesktop.Frames.getByIndex (i).Title
			y=left(z,4)
		if   y="Hans" then
				Msgbox "Die CSV-Datei 'Hans_Meerkatz*.CSV' ist bereits geöffnet und wird nun geschlossen!" & cHR(10) &_ 
				"Das Programm wird beendet!",64, "Fehlerroutine:"
					Stardesktop.Frames.getByIndex (i).Controller.Frame.Close(True)
				exit For
		end if
		Next i

End Sub
Gruß

Craig

Nie die Sicherungskopie vergessen!

════════════════════════════════════════════════
WIN 10 Pro 64-Bit • LO 7.4.5.1 (x64) • AOO 4.1.8

natal
Beiträge: 120
Registriert: So 8. Mär 2020, 20:03

Re: variable Zellenzahl ermitteln

Beitrag von natal » Sa 6. Feb 2021, 18:58

Noch ein Anhängsel
Zeile 79 sieht bei Dir so aus: sUrl= "file:///C:/temp%202021/Natal-Neu%20Makro/"
Ich habe sie ersetzt mit: sUrl="file:///home/servus/Schreibtisch/Ha/"

Wenn ich die Vorlage_P benutze, kann ich sehen, dass sie zumindest die beiden ersten Spalten schneller füllt als die Vorlage Natal 31.01.2021.
Ich gehe daher davon aus, dass Deine neue Vorlage schneller wäre.

Gruß natal

craig
* LO-Experte *
Beiträge: 1137
Registriert: Do 21. Apr 2016, 11:42

Re: variable Zellenzahl ermitteln

Beitrag von craig » Sa 6. Feb 2021, 19:38

Hallo Natal,
Zeile 79 sieht bei Dir so aus0sUrl= "file:///C:/temp%202021/Natal-Neu%20Makro/"
Ich habe sie ersetzt mit: sUrl="file:///home/servus/Schreibtisch/Ha/"
Sorry, hatte ich vergessen zuändern.

Im neuen Makro ist Zeile 79 = sUrl="file:///home/servus/Schreibtisch/Ha/"

In Vorlage_P ist nun auch eine Berechnung enthalten, gemäß:
=WENN(ODER(B4="";C5="");"";B4+$C$5)

Dies ist nicht im Makro:
Spalte E:
ab Zelle E6 bis Zelle Ex: =WENN(E5>=$F$2;"";E5+1)
Zeilennummer der Zelle Ex entspricht dem Inhalt von Zelle F2

Spalte F:
ab Zelle F4 bis Fx: =WENN(D4="";"";ZÄHLENWENN(INDIREKT("$D$4:$D$"&MAX(A:A))+3);E4))
Zeilennummer der Zelle Fx entspricht dem Inhalt von Zelle G2
Gruß

Craig

Nie die Sicherungskopie vergessen!

════════════════════════════════════════════════
WIN 10 Pro 64-Bit • LO 7.4.5.1 (x64) • AOO 4.1.8

natal
Beiträge: 120
Registriert: So 8. Mär 2020, 20:03

Re: variable Zellenzahl ermitteln

Beitrag von natal » Sa 6. Feb 2021, 20:36

Hallo
Das Ergebnis mit dem neuen Makro und der dazugehörigen Meldung.
Nach der Meldung stoppt der Ablauf.
Zusätzlich ein Bild von Anpassen→Ereignisse ?
Spalte E:
ab Zelle E6 bis Zelle Ex: =WENN(E5>=$F$2;"";E5+1)
Zeilennummer der Zelle Ex entspricht dem Inhalt von Zelle F2

Spalte F:
ab Zelle F4 bis Fx: =WENN(D4="";"";ZÄHLENWENN(INDIREKT("$D$4:$D$"&MAX(A:A))+3);E4))
Zeilennummer der Zelle Fx entspricht dem Inhalt von Zelle G2
Die Eingabe der Formeln habe ich bewusst weggelassen, da mir nicht klar war, ob Du nicht die Funktionen, die in diesen Zellen stehen sollten, etwas abwandelst, damit sie so oft wiederholt werden können, wie Werte in den Zellen F2 un G2 stehen
Dateianhänge
Bildschirmfoto vom 2021-02-06 20-32-51.png
Bildschirmfoto vom 2021-02-06 20-32-51.png (72.71 KiB) 4478 mal betrachtet
Bildschirmfoto vom 2021-02-06 20-02-23.png
Bildschirmfoto vom 2021-02-06 20-02-23.png (84.04 KiB) 4478 mal betrachtet

craig
* LO-Experte *
Beiträge: 1137
Registriert: Do 21. Apr 2016, 11:42

Re: variable Zellenzahl ermitteln

Beitrag von craig » Sa 6. Feb 2021, 21:06

Hallo Natal,
Natal hat geschrieben:Das Ergebnis mit dem neuen Makro und der dazugehörigen Meldung.
Nach der Meldung stoppt der Ablauf.
Diese Meldung kennzeichnet das Ende des Makros und soll Dir mitteilen, dass alle
Datensätze aus der CSV-Datei in das neue Dokument eingefügt wurden.

Jetzt öffne mal die "Hans_Meerkatz*.csv" und dann
Menü Datei → Dokumentvorlagen → Dokumentvorlage verwalten...

Was passiert dann?

Natal hat geschrieben:Zusätzlich ein Bild von Anpassen→Ereignisse ?
Der Makropfad ist in Ordnung.
Gruß

Craig

Nie die Sicherungskopie vergessen!

════════════════════════════════════════════════
WIN 10 Pro 64-Bit • LO 7.4.5.1 (x64) • AOO 4.1.8

natal
Beiträge: 120
Registriert: So 8. Mär 2020, 20:03

Re: variable Zellenzahl ermitteln

Beitrag von natal » So 7. Feb 2021, 10:42

Hi craig
Das Ergebnis von
Jetzt öffne mal die "Hans_Meerkatz*.csv" und dann
Menü Datei → Dokumentvorlagen → Dokumentvorlage verwalten...
sind 2 Meldungen (Bild1 und Bild2).

Hoffentlich hast Du dich nicht mit den Angaben von mir
Die Eingabe der Formeln habe ich bewusst weggelassen, da mir nicht klar war, ob Du nicht die Funktionen, die in diesen Zellen stehen sollten, etwas abwandelst, damit sie so oft wiederholt werden können, wie Werte in den Zellen F2 un G2 stehen
in die Irre führen lassen, denn sie sind nicht ganz korrekt.
Richtig hätte es lauten müssen:
  • Zelle E5 bekommt als unveränderlichen Inhalt die Formel: =WENN(E4>=$F$2;"";G2)
  • die Formel in Zelle E6 =WENN(E5>=$F$2;"";E5+1) wird so oft wiederholt, bis der Wert der Zelle F2 erreicht wird
  • die Zelle F4 bekommt als unveränderlichen Inhalt die Formel =WENN(D4="";"";ZÄHLENWENN(INDIREKT("$D$4:$D$"&(MAX(A:A))+3);E4))
  • die Formel in Zelle F5 =WENN(E5="";"";ZÄHLENWENN(INDIREKT("$D$4:$D$"&(MAX(A:A))+3);E5)) wird soft wiederholt, wie es belegte Zellen in der Spalt E gibt
Dateianhänge
Bild1.png
Bild1.png (80.49 KiB) 4470 mal betrachtet
Bild2.png
Bild2.png (79.64 KiB) 4470 mal betrachtet

craig
* LO-Experte *
Beiträge: 1137
Registriert: Do 21. Apr 2016, 11:42

Re: variable Zellenzahl ermitteln

Beitrag von craig » So 7. Feb 2021, 15:15

Hallo Natal,

die beiden Screenshots zeigen mir, dass Du mit dem richtigen Makro arbeitest.
Ist somit vollkommen korrekt.
Natal hat geschrieben:in die Irre führen lassen, denn sie sind nicht ganz korrekt.
Bis jetzt noch nicht.
Natal hat geschrieben:Richtig hätte es lauten müssen:
Bis ich die Logik im Makro umgesetzt habe, wird es aber noch eine Weile dauern.
Muss jetzt ersteinmal Schnee schieben :cry:

Bis dann...
Gruß

Craig

Nie die Sicherungskopie vergessen!

════════════════════════════════════════════════
WIN 10 Pro 64-Bit • LO 7.4.5.1 (x64) • AOO 4.1.8

craig
* LO-Experte *
Beiträge: 1137
Registriert: Do 21. Apr 2016, 11:42

Re: variable Zellenzahl ermitteln

Beitrag von craig » Mo 8. Feb 2021, 17:14

Hallo Natal,

es ist soweit:
  1. Dies ist eine überarbeitet Dokuvorlage. Die Änderungen habe ich in der Vorlage beschrieben:
    Vorlage_P.ots.zip
    (12.52 KiB) 187-mal heruntergeladen
    Ersetze Deine "Vorlage_P.ots" durch die neue "Vorlage_P.ots"
    und wie immer nur umbenennen von "Vorlage_P.ots.zip" in "Vorlage_P.ots"
  2. Ersetzte den bestehenden Makrocode durch diesen:

    Code: Alles auswählen

    REM  *****  BASIC  *****
    Option Explicit
    
    Dim oDocCSV as Object  
    Dim oDocAusVorlage as Object
    
    Dim oSheetAusVorlage as Object
    
    Dim nEndRow1 as Long
    Dim nEndRow2 as Long
    
    Dim nCnt1 as Long
    Dim nCnt2 as Long
    Dim nCnt3 as Long
    
    REM modCSVImport
    Sub [CSV_DATEN importieren]
    
    Dim oAllComponents as Object
    Dim oElements as Object
    Dim oElement as Object
    
    Dim oRange1AusVorlage as Object
    Dim oRange2AusVorlage as Object
    Dim oRange3AusVorlage as Object
    
    Dim oSheet as Object
    Dim oRange1 as Object
    Dim oRange2 as Object
    Dim oRange3 as Object
    Dim oRange4 as Object
    
    Dim oCellCursor as Object
    
    Dim fSekunde as Double
    Dim fTime as Double
    
    Dim mData1() as Variant	' Array für die Daten
    Dim mData2() as Variant	' Array für die Daten
    Dim mData3() as Variant	' Array für die Daten
    
    Dim sFileCSV as String
    Dim sPath as String
    Dim sFile as String
    Dim sUrl as String
    
    Dim bFound as Boolean
    
    	oDocAusVorlage=ThisComponent
    
    		oSheetAusVorlage=oDocAusVorlage.CurrentController.ActiveSheet
    			oRange1AusVorlage=oSheetAusVorlage.getCellRangeByName("A2:C2")
    			oRange2AusVorlage=oSheetAusVorlage.getCellRangeByName("A4:C86410")
    REM ---------------------------------------------------------------------------
    REM 				Zellinhalte löschen
    REM
    REM VALUE		Nummerische Werte
    REM DATETIME	Datum/Zeit-Werte
    REM STRING		Text
    REM ANNOTATION	Die Notiz
    REM FORMULA		Formeln
    REM HARDATTR	Die harten Formatierungen
    REM STYLES		Styles
    REM OBJECTS		Grafik
    REM EDITATTR	Textformartierungen ?
    			oRange1AusVorlage.ClearContents(com.sun.star.sheet.CellFlags.VALUE _
                             + com.sun.star.sheet.CellFlags.STRING _
                             + com.sun.star.sheet.CellFlags.DATETIME)
                             
    			oRange2AusVorlage.ClearContents(com.sun.star.sheet.CellFlags.VALUE _
                             + com.sun.star.sheet.CellFlags.STRING _
                             + com.sun.star.sheet.CellFlags.DATETIME)
                             
    
    REM ══════════════════════════════════════════════════════════════════════════════════════════════════════
    REM 				Hier die Pfadangabe, bzw. die URL ändern
    
    	' Unter Linux auch als URL angeben
    	sUrl="file:///home/servus/Schreibtisch/Ha/" 
    		sFile=dir(sUrl & "Hans*.csv")
    			sPath = convertFromUrl(sUrl) & sFile
    
    	
    REM ══════════════════════════════════════════════════════════════════════════════════════════════════════
    
    REM 			...................................
    REM Prüfen ob die CSV-Datei bereits geöffnet ist
    	sURL = ConverttoURL(sPath)
    	bFound=False
    		oAllComponents = StarDesktop.getComponents	
    			oElements = oAllComponents.CreateEnumeration
    	Do While oElements.HasMoreElements
    		oElement = oElements.NextElement
    		If oElement.hasLocation Then
    			If oElement.URL = sUrl Then
    					bFound = True
    					 Goto ErrorHandler
    				Exit Do
    			End If	
    		End If
    	Loop
    	
    REM -----------------------------------------------------------------------------------------------------
    REM Prüfung ob die Datei existiert.
    REM Dazu wird die "FileExists(sUrl)" aufgerufen;
    REM "FileExists(sUrl)" = TRUE		' Datei existiert
    REM "FileExists(sUrl)" = FALSE		' Datei existiert nicht oder der Dateiname ist falsch, bzw.
    REM der Dateiname entspricht nicht den Vorgaben, welche von diesem Makro gefordert werden
    	If FileExists(sUrl) Then
    		' "FileExists(sUrl)" = TRUE
    '		msgBox surl
    	Else
    		' "FileExists(sUrl)" = FALSE
        	msgBox "Die angegebene Datei:" & chr(10) & _
         			sFileCSV	 & chr(10) & _
         			"exisitiert nicht!"  & chr(10) & _
         		"--------------------------------"  & chr(10) & _
         		"Das Programm wird beendet"	,16, "Datei nicht vorhanden"
         			Exit Sub
      End If 
    
    REM 			...................................
    REM CSV-Datei öffnen
        sFileCSV = convertToUrl(sPath)
        if len(sFileCSV)>0 then
            dim mFileProps(2) as new com.sun.star.beans.PropertyValue
            mFileProps(0).Name = "FilterName" 	: mFileProps(0).Value = "Text - txt - csv (StarCalc)"
    		' der erste Token (59) der Filteroptionen gibt den Datenfeld-Separator an:
    		' Kommata	= 44
    		' Semikola	= 59
            mFileProps(1).Name = "FilterOptions" : mFileProps(1).Value = "44,34,76,1,,0,false,true,true,false"
    		' Datei im Hintergrund öffnen
            mFileProps(2).Name = "Hidden"		: mFileProps(2).Value = True
            oDocCSV = StarDesktop.loadComponentFromURL(sFileCSV, "_blank", 0, mFileProps())        
        end if
    
    REM 			...................................
    REM Daten aus dem CSV-File kopieren
    
    	oSheet=oDocCSV.CurrentController.ActiveSheet
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    			' CSV-Datei:	letzte befüllte Zelle
    			oCellCursor = oSheet.createCursor()
    	   			oCellCursor.GotoEndOfUsedArea(True)
    					nEndRow1 = oCellCursor.getRangeAddress.EndRow+1
    	
    		' CSV-Datei: Zellbereich "C2:E2"
    		oRange1=oSheet.getCellRangeByName("C2:E2")					' CSV-Daten kopieren
    		
    			' CSV-Datei: Zellbereich "B4:C (letzte Zeile)"
    REM getCellRangeByPosition ( nLeft as long, nTop as long, nRight as long, nBottom as long )
    			oRange2=oSheet.getCellRangeByPosition(1,3,2,nEndRow1)
    			' Leeres Array dimensionieren aus Spalte "AX" und "AZ"
    			oRange3=oSheet.getCellRangeByPosition(49,3,50,nEndRow1)
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    			mData1()=oRange1.getDataArray()	' CSV-Datei: Daten aus Zellebereich "C2:E2"
    			mData2()=oRange2.getDataArray()	' CSV-Datei: Daten aus Spalte "B" und "C"
    			mData3()=oRange3.getDataArray()	' CSV-Datei: Daten aus Spalte "AX" und "AZ" (Daten = "")
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    REM				CSV-Daten aus Array in neues Dokument schreiben
    		oSheetAusVorlage.getCellRangeByName("A2:C2").setDataArray(mData1())
    		oSheetAusVorlage.getCellRangeByPosition(2,3,3,nEndRow1).setDataArray(mData2())
    	
    
    REM neues Dokument: Inhalt "B2" kopieren und in  Zelle "B4" schreiben
    		oSheetAusVorlage.getCellRangeByName("B4").Value=	oSheetAusVorlage.getCellRangeByName("B2").Value
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    REM Zähler für Spalte A
    
    			' neues Dokument: letzte befüllte Zelle
    			oCellCursor = oSheetAusVorlage.createCursor()
    	   			oCellCursor.GotoEndOfUsedArea(True)
    					nEndRow2 = oCellCursor.getRangeAddress.EndRow+1 
    
    fSekunde=oSheetAusVorlage.getCellRangeByName("B4").Value
    fTime=oSheetAusVorlage.getCellRangeByName("B4").Value
    nCnt2=1	' Initialisierung: Zähler für Spalte "A"
    nCnt3=0
    Dim nUB as Long
    nUB=uBound(mData3())
    
    REM ............................................................................................................................................................
    
    			mData3(0)(1)=oSheetAusVorlage.getCellRangeByName("$B$2").Value
    			For nCnt1=1 To nEndRow1
    						If nCnt3 >nUB Then Exit For
    					If mData2(nCnt3)(0) = ""  OR mData2(nCnt3)(1) = "" Then
    							' DANN Arrayfeld = ""
    							mData3(nCnt3)(0)=""
    							mData3(nCnt3)(1)=""
    							nCnt3=nCnt3+1
    					' WENN nicht LEER, 
    					ElseIf mData2(nCnt3,0) >= 0 AND mData2(nCnt3,1) >= 0 Then
    						' Wen Zähler > uBound(mData3())
    						If nCnt3 >nUB Then Exit For
    							' DANN Spalte "A" inkrementieren
    							mData3(nCnt3)(0) = nCnt2
    							If nCnt1 = 1 Then
    								mData3(nCnt3)(1) = fTime+fSekunde					' Zeit für Zelle B5
    							Else
    								mData3(nCnt3)(1) = fTime+mData2(nCnt3)(0) 		'Zeitberechnung bis letzte Zeile
    							End IF
    								' Zähler inkrementieren
    								nCnt2=nCnt2+1
    								nCnt3=nCnt3+1
    					End If
    				Next nCnt1
    		
    
    			mData3(0)(1)=oSheetAusVorlage.getCellRangeByName("$B$2").Value
    
    '			oSheetAusVorlage.getCellRangeByName("$A$4:$B$23").setDataArray(mData3())
    			oSheetAusVorlage.getCellRangeByPosition(0,3,1,nEndRow1).setDataArray(mData3())
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    REM Zellen formatieren mit Formatcode 41 = HH:MM:SS  → 12:12:10
    REM https://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1i18n_1_1NumberFormatIndex.html
    		oSheetAusVorlage.getCellRangeByName("B2:C2").NumberFormat=41
    '		oSheetAusVorlage.getCellRangeByName("B4").NumberFormat=41
    		oSheetAusVorlage.getCellRangeByName("B4:C86410").NumberFormat=41
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    WennSpalteE
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    REM 			...................................
    REM CSV-Datei schließen
    	oDocCSV.Close(True)
    		Msgbox "Programmende:  'Sub [CSV_DATEN importieren]'"  & Chr(10) & _
    				    		"______________________________" & Chr(10)  & Chr(10) & _
    				    		"Es wurden " & nCnt3 & " Datensätze geschrieben.", 64,"Programmende"
    REM End If
    
    Exit Sub
    
    REM 			...................................
    ErrorHandler:
    
        Reset
    
    '	    MsgBox "Die CSV-Datei"  & Chr(10) & _
    '	    			sPath   & Chr(10) & _
    '	    			 "ist bereits geöffnet" & Chr(10) & _
    '	    			   "Bitte schließen Sie die Datei und starten das Programm erneut" & Chr(10) & _
    '	    		"______________________________" & Chr(10)  & Chr(10) & _
    '			   	"Das Programm wird beendet!"	,0,"Fehlermeldung"
    REM CSV-Datei schließen
    XClose
    End Sub
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    REM Diese Sub-Routine bildet diese Funktion nach:
    REM 		=WENN(E5>=$F$2;"";E5+1) 
    Sub WennSpalteE
    Dim oRangeE as Object
    Dim mData1() as Variant
    
    Dim nCellE5 as Long
    Dim nCellF2 as Long
    
    	oRangeE=oSheetAusVorlage.getCellRangeByPosition(4,5,4,nEndRow1)
    	mData1()=oSheetAusVorlage.getCellRangeByPosition(50,5,50,nEndRow1).getDataArray()
    		nCellE5 = oSheetAusVorlage.getCellRangeByName("E5").Value
    		nCellF2 = oSheetAusVorlage.getCellRangeByName("F2").Value
    
    REM Wenn-Funktion
    			If nCellE5 >= nCellF2 Then
    					mData1(0)(0) =""
    			else 
    					mData1(0)(0) =nCellE5+1
    			End If
    			
    		For nCnt1 = 1 To uBound(mData1())
    			If mData1(nCnt1-1)(0) <= nCellF2 -1 Then				
    						mData1(nCnt1)(0) = mData1(nCnt1-1)(0)+1
    			else
    					mData1(nCnt1)(0) = ""
    			End If
    		Next  nCnt1		
    			' berechnete Daten in Zellbereich schreiben
    			oRangeE.setDataArray(mData1())
    
    ZaehlenwennSpalteF
    End Sub
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    REM Diese Sub-Routine bildet diese Funktion nach:
    REM 	=WENN(E5="";"";ZÄHLENWENN(INDIREKT("$D$4:$D$"&(MAX(A:A))+3);E5)) 
    Sub ZaehlenwennSpalteF
    Dim	oRangeD as Object
    Dim	oRangeF as Object
    Dim	oRangeFnF2 as Object
    Dim oFunction as Object
    Dim oCellE as Object
    Dim oCellF as Object
    
    Dim mData1() as Variant
    
    Dim nIsRow as Long
    Dim nF2 as Long
    Dim nDiffMinMax as Long
    	' Service zur Bereistellung der Function "Zählenwenn..."
        oFunction = createUnoService("com.sun.star.sheet.FunctionAccess")
    			' Referenz: Zellbereich "D4 bis letzte Zelle"
    			oRangeD=oSheetAusVorlage.getCellRangeByPosition(3,4,3,nEndRow1)
    
    			' Referenz: Zellbereich "F4 bis letzte Zelle"
    			oRangeF=oSheetAusVorlage.getCellRangeByPosition(5,4,5,nEndRow1)
    		' Wert aus Zelle F2 ermitteln
    		nF2=oSheetAusVorlage.getCellRangeByName("F2").Value
    		' Zeilenanzahl berechnen "(F2-G2)+4"
    		nDiffMinMax=nF2-oSheetAusVorlage.getCellRangeByName("G2").Value+4
    		' Zellbereich (Spalte F) für die Dimensionierung des Arrays festlegen
    		oRangeFnF2=oSheetAusVorlage.getCellRangeByPosition(5,4,5,nF2-1)
    			' Array mit Daten füllen
    			mData1()=oRangeFnF2.getDataArray()
    			
    			For nCnt1 = 4 To nDiffMinMax
    					oCellE = oSheetAusVorlage.getCellByPosition(4,nCnt1)
    					oCellF = oSheetAusVorlage.getCellByPosition(5,nCnt1)
    REM Zählenwenn...
    Dim aArgument(1) as variant
    			aArgument(0)=oRangeD				' Zellbereich Spalte D für die Zählenwenn-Funktion
    			aArgument(1)=oCellE.Value		' [aktueller Zellwert] für die Zählenwenn-Funktion → =Zählenwenn($D$4:$D$n;[oCellE.Value])
    				mData1(nCnt1-4)(0)= oFunction.callFunction( "COUNTIF", aArgument() )		' Ergebnis der Zählenwenn-Funktion in Array schreiben
    		Next nCnt1
    		
    			' berechnete Daten in Zellbereich schreiben
    			oRangeFnF2.setDataArray(mData1())
    End sub
    
    REM ----------------------------------------------------------------------------------------------------------------------------------------------
    REM CSV-Datei schließen, wenn geöffnet.
    Sub XClose
    dim i As Integer
    dim ncnt1
    dim z
    dim y
    REM CSV-Datei schließen
    'xray 
    nCnt1=Stardesktop.Frames.Count
    		for i = 0 to nCnt1-1
    			z=Stardesktop.Frames.getByIndex (i).Title
    			y=left(z,4)
    		if   y="Hans" then
    				Msgbox "Die CSV-Datei 'Hans_Meerkatz*.CSV' ist bereits geöffnet und wird nun geschlossen!" & cHR(10) &_ 
    				"Das Programm wird beendet!",64, "Fehlerroutine:"
    					Stardesktop.Frames.getByIndex (i).Controller.Frame.Close(True)
    				exit For
    		end if
    		Next i
    
    End Sub
Deine Wenn- und Zählenwenn-Formeln werden durch das Makro abgearbeitet,
es erscheinen also nur die Ergebnisse der Berechnungen im Tabellenblatt.

Ich hoffe ich habe die Logik richtig erfasst.

Bin gespannt auf die Rückmeldung... :D
Gruß

Craig

Nie die Sicherungskopie vergessen!

════════════════════════════════════════════════
WIN 10 Pro 64-Bit • LO 7.4.5.1 (x64) • AOO 4.1.8

natal
Beiträge: 120
Registriert: So 8. Mär 2020, 20:03

Re: variable Zellenzahl ermitteln

Beitrag von natal » Mo 8. Feb 2021, 17:22

Hi craig
Beim Vergleich meiner Vorlage_P.ods vom 04.Feber und deiner Vorlage_P.ots vom 06. Feber , habe ich festgestellt, dass Teile der Formel, die im großen gelben Feld gespeichert sind, unterschiedlich sind.
Das betrifft auch die Formel in Zelle G12.
Die Unterschiede im großen gelben Feld sind:
in meiner Vorlage steht (F4:F300) in Deiner (F32:F328)
anstatt F4 in meiner Vorlage steht F32 in deiner

In Zelle G12 steht bei mir: =WENN(F4="";"";WENN(MAX(A:A)=SUMME(F4:F400);"OK";"nicht OK"))
und bei Dir
=WENN(F32="";"";WENN(MAX(A:A)=SUMME(F32:F428);"OK";"nicht OK"))

Alle Unterschiede beginnen mit der Spaltenbezeichnung F.
Als Anhang die neue Vorlage_P.neu.ods

Servus, und fröhliches Schippen, bei uns beginnt es auch zum Schneien.

Gerade habe ich gesehen, das ich von Dir eine Antwort bekommen habe.
Muß ich mir noch ansehen
Dateianhänge
Vorlage_P.neu.ods
(10.37 KiB) 197-mal heruntergeladen

natal
Beiträge: 120
Registriert: So 8. Mär 2020, 20:03

Re: variable Zellenzahl ermitteln

Beitrag von natal » Mo 8. Feb 2021, 18:51

Hallo craig
Dein Hinweis, dass max(A:A) reduziert werden sollte, ist natürlich sinnvoll, da habe ich geschlafen.
Das trifft auch auf die Formel in F4 zu.
Es reicht auch (A4:A50000).
Neugierig, warum A86404 und nicht A86405?
In Deiner neuen Vorlage steht aber weiterhin in G11 und G12 (A:A), kann ich ändern.
Auch noch neugierig: kannst Du dir vorstellen, wo der Grund für die scheinbar selbstständigen Änderungen der Zellennummern der Spalte F liegt?

Servus


An alle, die das LibreOffice-Forum gern nutzen und unterstützen wollen:


Bitte helfen Sie uns mit 7 Euro pro Monat.
Durch Ihren Beitrag tragen Sie dazu bei, unsere laufenden Kosten für die kommenden Monate zu decken.
Unkompliziert per Kreditkarte oder PayPal.
Als ein kleines Dankeschön werden Sie im LO-Forum als SUPPORTER gekennzeichnet.



Antworten