aus einer Zelle ein Teilstring auslesen

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

Collector
*
Beiträge: 15
Registriert: Sa, 21.01.2006 18:54

Syntaxfehler: unerwatetes Symbol &

Beitrag von Collector »

Hi folks

habe ein Problem bzw. beim umsetzen wird ein Syntaxfehler angezeigt.

Code: Alles auswählen

for p = 1 to 100      	'diese for-next Schleife soll 100 mal durchlaufen werden, in unserem
								'Fall die Plätze von 1 bis 100
								
			for l = 0 to uBound(aLand)	'diese for-next Schleife soll 8 mal (Länderanzahl
										'durch uBound ermittelt) durchlaufen.


				if instr(sStr, " " & aLand(l) & " " & p )then _
					oSheet.getCellRangeByName(aSpalte(l))& p).string = p 		
						elsif instr(sStr, " " & aLand(l) & " " & p "," )then _
							oSheet.getCellRangeByName(aSpalte(l))& p).string = p
						 		elsif instr(sStr, " " & aLand(l) & " " & p )then _
									oSheet.getCellRangeByName(aSpalte(l))& p).string = aLand(l) & " " & p
bei

Code: Alles auswählen

if instr(sStr, " " & aLand(l) & " " & p )
zeigt er mir ein Syntax fehler " unerwatetes Symbol & " an.

Meine Vermutung ist das p kein String sonder ein Zahl ist.

Meine Frage muss ich erst p zu einem String umwandeln ?



Vielen Dank im Vorraus für Eure Antworten

Collector
Die Menschen fangen immer erst mit Fehlern an, bevor sie sich bessern können. (Mengtse)
Toxitom
********
Beiträge: 3768
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Beitrag von Toxitom »

Hey Collector,
Meine Vermutung ist das p kein String sonder ein Zahl ist.
Meine Frage muss ich erst p zu einem String umwandeln ?
Nein - und Nein. Also, a) die Vermutung ist falsch und b) du müsstest eine Zahl nicht erst in einen String verwandeln. Bei der Stringverkettung macht das OOo Basic automatisch.

Dein Fehler liegt in der Syntax selbst. InStr() erwartet zwei Parameter, also den zu durchsuchenden String sowie den Suchstring. Den zweiten kannst du nicht erst im Aufruf "zusammenbauen". Wäre in deinem Code eigentlich auch schlechter Programmierstil.
Führe eine neue Variable ein, weise diese zu, und arbeite dann damit:-)

Code: Alles auswählen

sTxt = " " & aLand(l) & " " & p 
inStr(sStr, sTxt)
Dann sollte es funktionieren.

Gruss
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Karolus
********
Beiträge: 7443
Registriert: Mo, 02.01.2006 19:48

Beitrag von Karolus »

Hallo

Die Fehlermeldung :
Syntax fehler " unerwatetes Symbol & " an.
kommt dann wenn kein Leerzeichen zwischen Variablen und &-zeichen eingefügt ist.

@Thomas

Dein Code vom 25.11.06 17:56 läuft

Code: Alles auswählen

 if instr(sStr, " " & aLand(j) & " " & n ) then
                  oSheet.getCellRangeByName(aSpalte(j) & n).string = aLand(j) & " " & n
sollte aber 'oSheet.getCellRangeByName(aSpalte(j) & i).string = aLand(j) & " " & n' lauten,
(i ist der Zeilenindex vom übergebenen 'sStr')
i ist aber in dieser Sub nicht definiert, und erzeugt deshalb eine Fehlermeldung.
Daher hab ich nochmal alles in einem Makro zusammengefasst :

Code: Alles auswählen

sub chartplatz

dim z as long,chartstring as string
oSheet = thisComponent.sheets(0) 'das erste Tabellenblatt
for z = 3 to 100  'Zeile ,wenns funktioniert 30000 eintragen
	chartString = oSheet.getCellRangeByName("D" & z).string
	aLand() = Array("D", "USA") 'Länderkürzel ergänzen
	aSpalte() = array("G", "H")   'Spalten ebenso viele wie ^Länderkürzel
	for l = 0 to ubound(aLand())
		for p = 1 to 9  'erste Platzierungsziffer
		if instr(chartString," " & aLand(l) & " " & p ) then
		outzelle = oSheet.getCellRangeByName(aSpalte(l) & z)
		outzelle.string = aLand(l) & " " & p
		end if
		for s = 0 to 9  'zweite Platzierungziffer
			if instr(chartString," " & aLand(l) & " " & p & s ) then
			outzelle.string = aLand(l) & " " & p & s
			end if
			
			next s '2.Ziffer
		next p  '1.Ziffer
	next l     'nächstes Länderkürzel
 next z   'nächste Zeile

end sub
Gruß Karo
Collector
*
Beiträge: 15
Registriert: Sa, 21.01.2006 18:54

Beitrag von Collector »

Danke Toxitom und Karolus,

Werde versuchen mir gleich ein guten Programmstil angewöhnen, wenn ich bis jetzt noch nicht gut programmieren kann, sollte dies aber möglich sein. :-).

Ich muss aber hier etwas los werden.

1. Super wie Ihr mich unterstützt und das auch noch PRONTO.

2. Danke das Ihr mir gleich am Anfang aufzeigt wo sich Fehler einschleichen können. (siehe Programmstil). Gerade am Anfang sollte man sich sowas nicht angewöhnen, da später es schwerer ist sich das ab zugewöhnen.

@Karolus
kommt dann wenn kein Leerzeichen zwischen Variablen und &-zeichen eingefügt ist.
Dies glaube ich nicht, da Leerzeichen vorhanden sind, dies hatte ich schon probiert. Doch werde ich es nochmal ausprobieren. Den Vorschlag (Programmstil) von Toxitom werde ich aber am Ende vorziehen. Der Vorteil ist, das man diesen Programmschritt besser dokumentieren bzw. kommentieren kann.

Edit 1. Ich muss mich entschuldigen Karolus. Du hast vollkommen Recht. Ich hatte die nächste Zeile nicht beachtet. Habe mich zu weit aus dem Fenster gelehnt. Werde demnächst erst mal genauer testen, bevor ich ein Kommentar abgebe.

:oops: Collector :oops:
Die Menschen fangen immer erst mit Fehlern an, bevor sie sich bessern können. (Mengtse)
Collector
*
Beiträge: 15
Registriert: Sa, 21.01.2006 18:54

Beitrag von Collector »

Hi folks

Es hat geklappt, Danke nochmal. Ohne Eure Hilf wäre ich noch Monate entfernt gewesen.

Werde mal den Code mit meinen vielleicht übertriebenen Erläuterungen hier reinstellen
Natürlich werde ich noch Feintuning betreiben.
Doch konnte nicht mehr warten.


Code: Alles auswählen

Option Explicit		'Hier  erzwinge ich, das alle  Variablen, die in der
				    'Prozedur vorkommen,  explizit deklariert Die (ausdrück-
					'lich bekannt gemacht)werden müssen.				
					'Um Fehler zu  vermeiden und die Lesbarkeit zu erhö-
					'hen, sollte man sich  angewöhnen, die  Variablen am
					'Anfang  zu definieren. Es ist aber nicht  unbedingt
					'notwendig.									
					'Der Befehl  "Option Explicit" muss am Anfang eines	
					'Programms stehen.
																		
'-----------------------------------------------------------------------    
'---------- Hier werden öffentliche (lokale) Variablen definiert--------                  	
'-----------------------------------------------------------------------
					
					 'Öffentliche Variablen werden im Kopfbereich eines	
					 'Moduls  mit dem Schlüsselwort Dim  definiert. Sie 	
					 'stehen allen Modulen in ihrer Bibliothek zur Ver-	
					 'fügung.											
					 'Eine lokale Variable steht nur solange zur Verfüg-	
					 'ung, wie das verknüpfte Makro ausgeführt wird, da-	
					 'nach wird die Variable zurückgesetzt.				
																	
																	
dim oSheet as object	'die Variable "oSheet" soll das Tabellenbl. als	
						'Objekt aufnehmen.                              
            			'Die Variable Objekt ist nicht nur ein Datentyp,
            			'es werden noch die benötigten Bearbeitungsfunk-
            			'tionen mitgeliefert					 		
            			
'-----------------------------------------------------------------------
'-----------------------   Hauptprogramm  ------------------------------
'-----------------------------------------------------------------------
                  														
sub Hauptprogramm	'Hier startet das Programm bzw. die Prozedur (Macro)
					'mit seinen Unterprogrammen (Prozeduren oder  Funk-	
					'tionen)									
    																	
    	init		 'In dieser Prozedur sollen die Variablen deklariert
    				 'werden.
   
    	hole_Zeichenkette	'Mit dieser Zeile wird die hole_Zeichenkette
							'Prozedur aufgerufen.
							
end sub		'Hier endet das Hauptprogramm								

'-----------------------------------------------------------------------
'------------------  Init Prozedur  ------------------------------------
'-----------------------------------------------------------------------
                  														
sub init	
				  'der Variablen "oSheet" wird ein objekt übergeben,näm-
				  					  'lich thisComponent,damit sprechen
	oSheet = thisComponent.sheets(0)  'wir das aktuelle Dokument an und 
									  'mit dem Zusatz .sheets(0)wird auf
				  'das erste Tabellenblatt verwiesen.  					
    
end sub		'Ende von der Prozedur init									
																		
'-----------------------------------------------------------------------
'---------------------  hole Zeichenkette Prozedur ---------------------
'-----------------------------------------------------------------------

sub hole_Zeichenkette 													
																		
   dim z as long			  	  'die z Variable dient als Zählvariable
   dim sZellString as String  	  'genauer gesagt für die Zeilen,es wird
   								  '"long" benutzt weil es mehr als 32767
   	  'Zeilen sind, die untersucht werden sollen. Variable "sZellString"
   	  'soll später die Zeichenkette(String)die in der Zeile vorkommt auf-
   	  'nehmen.
   	  															

	z = 1	' in der 1.Zeile soll die Suche starten.	|
							    
	do until oSheet.getCellRangeByName("D" & z).string = "" 
	
		'die do-until-loop Schleife wird so lange ausgeführt bis eine
		'bestimmte Bedingung (""=leer) nicht erfüllt is.Mit dem Anhang
		'.getCellRangeByName lade ich den Inhalt der Zelle direkt über
		'den Namen in unserem Beispiel D1
 						
		sZellString = oSheet.getCellRangeByName("D" & z).string							 
						
		'der gefundene Zellinhalt wird der Variable sZellString übergeben.
           
           			
           		vergl_Zeichenkette (sZellString, z)	'hier benutze ich die Funktion
           											'"vergl_Zeichenkette" und über-
           					'gebe die benötigten Parameter(sZellString,i) 
           												
            
            z = z+1		'die Zeilennummer wird um eins erhöht.
            
   		loop			'die Schleife beginnt von vorn.


end sub      'Ende der Prozedur hole_Zeichenkette

'-------------------------------------------------------------------------------------
'------------------------ vergleiche Zeichenkette  -----------------------------------                  	
'-------------------------------------------------------------------------------------                  	
                  	
                  	
                  	
  sub vergl_Zeichenkette(sStr as string, iZeile as long)	'Wenn die Prozedur bzw. Funktion
  															'aufgerufen bzw. gestartet wird
  															'müssen zwei Parameter schon vor-
  								'vorhanden sein. In unserem Fall bekommt die Variable
                  				'"sStr" die Zeichenkette von sZellString und die Variable "iZeile"
                  				'den Wert von z 
                  	
                  	
   dim aLand()		'hier wird die Variablen "aLand" zu einem dynamischen Datenfeld 
    				'defeniert. Das bedeutet, das erst später die Anzahl der Indexe  
    				'bestimmt wird.                                                 
    				
   dim aSpalte() 	'jedes Land bekommt eine Spalte zu gewiesen.
   	  
   dim p as integer				'die Laufvariable "p" soll für den Peak bzw. Platz sein 
   dim l as integer	    		'die Laufvariable "l" soll für die Länder sein
   dim sTeilstring as String	'das wird die gesuchte Zeichenkette sein
   
	aLand = Array("D", "USA", "GB", "I", "NL", "F", "S", "CH")	'hier bekommen die Variablen
																'ihre Zuweisungen bzw.werden
							  'die Arrays gefüllt aLand(0)=D; aLand(1)=USA; aLand(2)=GB; usw.
							  'somit wäre aLand(7) dimensioniert
	
	aSpalte = Array("E", "F", "G", "H", "I", "J", "K", "L") 'jedes Land bekommt später eine Spalte
															'zugewiesen.

		for p = 1 to 100      	'diese for-next Schleife soll 100 mal durchlaufen werden, in unserem
								'Fall für die Charplätze von 1 bis 100
								
			for l = 0 to uBound(aLand)	'diese for-next Schleife soll 8 mal (Länderanzahl
										'durch uBound ermittelt) durchlaufen.
										
			sTeilstring =  " " & aLand(l) & " " & p 'hier bekommt die Variable die Zeichenkette die
													'gesucht wird
			
										
            if instr(sStr,sTeilstring) then
                  oSheet.getCellRangeByName(aSpalte(l) & iZeile).string = p

										
							'mit instr wird die Zeichenkette "sStr" auf ein Teilstring
							'1.ersten Durchlauf wäre dies " D 1" untersucht
							'wenn (then) gefunden führe 
							'oSheet.getCellRangeByName(aSpalte(l) & iZeile).string = p
							'hier soll der Wert p bei Angabe des Zellenname (E1)in die
							'Zelle geschrieben werden.
											
             end if		
          next l
       next p 
      
end sub
Die Formatierung sieht hier nicht so toll aus, muss mal nachschauen warum das so ist. Viel Spass damit.

So, dies ist das Programm von Toxitom, was von mir als Anfänger kommentiert und nach meinem Geschmack verändert wurde.

Ich hoffe meine Kommentare sind nicht gar so falsch.

Collector
Die Menschen fangen immer erst mit Fehlern an, bevor sie sich bessern können. (Mengtse)
Toxitom
********
Beiträge: 3768
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Beitrag von Toxitom »

Hey Collector,

das ist schon mal gut :-)
Die Kommentierung korekt (mit kleinen Ausnahmen) und sehr verständlich. So kann man es lernen :-)
Die kleinen Ungenauigkeiten:
dim aLand() 'hier wird die Variablen "aLand" zu einem dynamischen Datenfeld
'defeniert. Das bedeutet, das erst später die Anzahl der Indexe
'bestimmt wird.
Ein "dynamisches Datenfeld" ist gut ;-) - Landläufig nennt sich das einfach ein "Array", also eine Datengruppe. Lediglich die Dimension (alos die Anzahl der Datenfelder) wird noch nicht fixiert. Aber wenn du deinen Text verstehst, ist das OK :-)

Soweit so gut, leider hat der Code noch eine logische Schwäche. Das hatte ich dir ja schon damals geschrieben.
Aktuell liest du nämlich einen String aus, der wie folgt aufgebaut ist:

Leerzeichen - Länderkürzel - Leerzeichen - Zählnummer p

Das Ergebnis ist aber nicht eindeutig!
Beispiel:
Im Text steht "... D 112" - Deine Zählnummer ist 1 oder 11 -> jedesmal wird der Eintrag "gewählt" denn der zusammengesetzte String " D 1" ist enthalten!

Wenn ich mich noch recht errinnere, wurden alle Länderkennzeichen immer mit einem Semikolon (;) abeschlossen bis auf den letzten Eintrag. Insofern könntest du den Eintrag eindeutig idenitfizieren mit der folgenden Kette:
Leerzeichen - Länderkennzeichen - leerzeichen - Zählnummer - Semikolon.
Das würde funktionieren bis auf den letzten Eintrag - da fehlt ja das Semikolon. Also, fügst du das zuerst hinzu, dann würde der Rythmus immer gehen und die Logik stimmt :-)
Das Semikolon fügst du hinzu in einer Zeile ziemlich am Anfang, vor den Schleifen:

Code: Alles auswählen

sStr = sStr & ";"
Dann musst du natürlcih deine Suchstrings noch entsprechend anpassen - fertig :-)

Gruss
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Collector
*
Beiträge: 15
Registriert: Sa, 21.01.2006 18:54

mehr dynamisches Array ?

Beitrag von Collector »

Hi Toxitom

Danke, dies konnte ich aber nur mit Deiner Hilfe.

Die Erläuterungen habe ich (siehe ISBN Nr.) auch von Dir. (hat einer im Forum erwähnt). Mit der Einschränkung das ich meine holprigen Worte benutzt habe.

Danke für die Tips zum Feintuning.

Als nächstes habe ich vor, dass bei den Interpreten der Vornamen und dann der Nachname gedreht wird und das Komma dabei entfällt. Zur Zeit steht Nachname, Vorname drin.
Das soll aber erst später in Angriff genommen werden. Als erstes werde ich nach doppelten Einträge suchen lassen.

:oops: Was wohl nicht so schwierig erscheint :oops:

Die Suchroutine (Aufnahme des Strings) liegt ja schon vor und eine Vergleichsoperation werde ich wohl hinkriegen.

Wenn ich das erledigt habe soll er auf meiner Festplatte die jeweiligen Titel suchen und wenn vorhanden markieren.

Also wie Du siehst habe ich noch einiges vor mit der Liste, dabei kommt es mir nicht darauf an, eine private Liste zu erstellen sondern das programmieren in bescheidenen Maßen (für den Hausgebrauch) zu erlernen.

Deshalb werde ich noch öfters bei Euch posten müssen.

Collector

Edit 1: Habe da noch eine Frage zum dynamisches Datefeld bzw. Array. In meinem Fall ist das Feld eindimensional z.B array(7), aber wie sieht ein dynamisches mehrdimensionales Array (7,5) aus. Gibt es sowas überhaupt ? rein Intresse halber.
Die Menschen fangen immer erst mit Fehlern an, bevor sie sich bessern können. (Mengtse)
Collector
*
Beiträge: 15
Registriert: Sa, 21.01.2006 18:54

ein einfaches Anführungszeichen wird vorne angestellt

Beitrag von Collector »

Hi folks

Habe ein Problem bei meinem Macro

es wird bei dem Programm ein einfaches Anführungszeichen (') vor der Zahl geschrieben. Dies ist aber kein Text sondern muss etwas anderes bedeuten. Denn es versteckt sich, bzw. es erscheint nur wenn ich in der Zelle bin.
Habe auch mal probiert das Zeichen zu Suchen leider ohne Erfolg nur die in den normalen Text habe ich gefunden. Wie bekomme ich das gebacken bzw. kann ich das entfernen. gerade bei der Sortieung ist es nicht schön wenn 1; 10; 11; ...2; 20; 21; usw. als Resultat kommt.

dies habe ich im Programm ausprobiert.

Code: Alles auswählen

dim s as integer
s=p
und s bei der Ausgabe eingesetzt, es hat aber wenig gebracht, nämlich gar nichts.

Kann mir einer etwas über das versteckte ' einfache Anführungszeichen (das Zeichen über #) sagen.

Vielen Dank im Vorraus

Collector
Die Menschen fangen immer erst mit Fehlern an, bevor sie sich bessern können. (Mengtse)
Toxitom
********
Beiträge: 3768
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Beitrag von Toxitom »

Hey Collector,
aber wie sieht ein dynamisches mehrdimensionales Array (7,5) aus. Gibt es sowas überhaupt ? rein Intresse halber.
Ja, es gibt mehrdimensionale Arrays. Auch in OOo. Stell es dir als Array von Arrays vor, also die erste Dimension umfasst 8 Elemente, jedes dieser acht Elementen wiederum besteht aus weiteren 6 Elementen (Array(7,5)).
es wird bei dem Programm ein einfaches Anführungszeichen (') vor der Zahl geschrieben. Dies ist aber kein Text sondern muss etwas anderes bedeuten. Denn es versteckt sich, bzw. es erscheint nur wenn ich in der Zelle bin.
Dann wird die Zahl als Text in die Zelle geschrieben. Das bedeutet, du kanst damit nicht mehr rechnen, die Sortierung schlägt fehl...
Das passiert immer dann, wenn du auch in Basic die Zahl in Textform hast (also z.B. in einer String-Variablen) und sie dann in die Zelle einträgst - als String.
Um das zu vermeinden, wandele sie vorher um:

Code: Alles auswählen

dim n as integer, s as string
s = 12      ' in s steht jetzt "12" als String!
n = cint(s)   'in n steht jetzt "12" als Zahl (integer)
oZelle.string = s     ' in der Zelle steht die 12 als Text, mit dem Hochzeichen
oZelle2.value = n   'in der Zelle steht 12 als Zahl, ohne Hochzeichen
Gruss
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Collector
*
Beiträge: 15
Registriert: Sa, 21.01.2006 18:54

Beitrag von Collector »

Hi toxitom

Danke, für die Antwort

Werde es im Programm versuchen einbauen.



Die Frage mit dem Array habe ich falsch gestellt. Ich wollte wissen wie ein

mehrdimensionales dynamisches Array aussieht bzw. difiniere

im Program ist es eine Dimension

dim aLand() <---- das wollte ich fragen wie das bei mehr Dimension aussieht.

aLand = Array("D", "USA", "GB", "I", "NL", "F", "S", "CH") <----und wie das

Collector
Die Menschen fangen immer erst mit Fehlern an, bevor sie sich bessern können. (Mengtse)
Antworten