Das Notes Forum

Domino 9 und frühere Versionen => ND7: Entwicklung => Thema gestartet von: Dubidu am 14.03.08 - 16:48:58

Titel: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 14.03.08 - 16:48:58
Codeblock wird nicht ausgeführt
by Dubidu


Hi an alle!
Ich habe momentan das Problem, dass bei mir eine Funktion bzw. die ForAll-Schleife nicht ausgeführt wird, alles vor der Schleife jedoch schon!

Global initialisiert:

Code
Public computerWorkerList List As workerComputer ' Used by function generateWorkerComputer

Code
Property Get compareWorker(newWorker As String) As Boolean
	
	Print "Hallo Welt!" ' Wird ausgeführt!!!
	
	Forall worker In computerWorkerList
		
		Print "Hello World!" ' Wird nicht ausgeführt!
		
		If worker.GetWorker = newWorker$ Then
			msg$ = "Mitarbeiter " & newWorker$ & " wurde schon einem Computer zugeordnet"
			Messagebox msg$
			compareWorker = False
		Else
			compareWorker = True
		End If
	End Forall
End Property

Es gibt zwei seltsame Verhaltensweisen:


Hier die Funktion, die die Get-Funktion oben aufruft:

Code
Sub generateWorkerComputer
	
	newWorker$ = Inputbox$("Bitte Mitarbeiter eingeben")
	
	If (compareWorker(newWorker$)) = False Then ' Controlls if worker is already stored
		Exit Sub	
	End If

...
...

End Sub



Liebe Grüße
Dubidu :)
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: ata am 14.03.08 - 20:00:24
... ist in deiner Liste von Objekten den etwas enthalten - ich nehme an es handelt sich bei "computerWorkerList" um ein Objekt oder Array?

Sollte es eine Liste sein, dann muß nur mit ...

IsElement( computerWorkerList( "newWorker" ) )

... geprüft werden.

Bei der Parameterübergabe dimensionierst du "newWorker" als String - im Verlauf des Codes verwendest du dann die implizite Deklaration zusätzlich - völlig unnötig.

Verwende auf jeden Fall "Option Declare" oder "Option Explicit" in den Global Declarations - das ist sauberer - und du brauchst weniger Sonderzeichen zu tippen...  ;D ;)

Toni

PS: Hast du auch einen regulären Vornamen? Es würde es persönlicher machen...
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: koehlerbv am 15.03.08 - 00:18:32
PS: Hast du auch einen regulären Vornamen? Es würde es persönlicher machen...

Zustimmung. Das "Dubidu" klingt nur gaga und motiviert nicht zum Antworten. Manche kapieren einfach nicht, dass hinter Forumsregeln auch kluge Gedanken und lange Erfahrungen stecken.

Bernhard
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 09:23:11
Hi ata,
danke, für deine Antwort!

... ist in deiner Liste von Objekten den etwas enthalten - ich nehme an es handelt sich bei "computerWorkerList" um ein Objekt oder Array?

computerWorkerList ist eine Liste, wie ganz oben im Quellcode erkenntlich ist. Hast du vermutlich übersehen(?).

Zitat
Sollte es eine Liste sein, dann muß nur mit ...

IsElement( computerWorkerList( "newWorker" ) )

... geprüft werden.

Stimmt, das ist auch möglich, nur habe ich dann das Problem, dass ich dann nicht mehr ohne weiteres die Möglichkeit habe, Vor- und Nachname zu kontrollieren, falls sich jemand beim Vor- oder Nachnamen vertippt hat. Dann wäre es nämlich noch möglich nachzufragen, ob das der Mitarbeiter ist, den man anlegen wollte.

Zitat
Bei der Parameterübergabe dimensionierst du "newWorker" als String - im Verlauf des Codes verwendest du dann die implizite Deklaration zusätzlich - völlig unnötig.

Ja, stimmt. Danke für den Hinweis.

Zitat
Verwende auf jeden Fall "Option Declare" oder "Option Explicit" in den Global Declarations - das ist sauberer - und du brauchst weniger Sonderzeichen zu tippen...  ;D ;)

Das hat den Nachteil, dass ich nicht auf den ersten Blick sehen kann, um welche Variable es sich handelt.

Zu meine Problem nochmal:
Wenn ich die ForAll-Schleife in die generateWorkerComputer-Methode einfüge, dann funktioniert alles einwandfrei. Wenn ich daraus jedoch eine eigene Methode mache, dann wird die Schleife anscheinend erst gar nicht ausgeführt!

Zitat
PS: Hast du auch einen regulären Vornamen? Es würde es persönlicher machen...

Ist es ok, wenn ich mich Giordano nenne? Das ist zwar nicht mein richtiger Vorname, aber das sagt schon etwas über meine Herkunft aus.
Eine gewisse Anonymität ist mir zu Zeiten wie diese einfach wichtig.

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 09:44:26
Den Fehler habe ich nun gefunden.
Wenn die Liste computerWorkerList leer ist, dann springt der Interpreter erst gar nicht in die Forall-Schleife rein.
In der Forall-Schleife habe ich jedoch compareWorker auf True initialisiert, falls der Mitarbeiter nicht schon angelegt angelegt wurde. Da der Interpreter jedoch nicht in die Schleife reinspringt, wird die Variable niemals auf true gesetzt und so muss ich sicherstellen, dass ich vorher die Variable auf true setze und später in der Schleife ggf. wieder auf false, wenn der Mitarbeiter schon existiert;

Code
Property Get compareWorker(newWorker As String) As Boolean
	
	compareWorker = True
	
	Forall worker In computerWorkerList
		
		If worker.GetWorker = newWorker$ Then
			msg$ = "Mitarbeiter " & newWorker$ & " wurde schon einem Computer zugeordnet"
			Messagebox msg$
			compareWorker = False
		'Else
		'	compareWorker = True
		End If
	End Forall
End Property

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: MadMetzger am 17.03.08 - 09:51:32

Zitat
Verwende auf jeden Fall "Option Declare" oder "Option Explicit" in den Global Declarations - das ist sauberer - und du brauchst weniger Sonderzeichen zu tippen...  ;D ;)

Das hat den Nachteil, dass ich nicht auf den ersten Blick sehen kann, um welche Variable es sich handelt.

Wieso verhindert das Option Declare, dass du auf den ersten Blick siehst, um welche Variable es sich handelt? Verstehe ich nicht ganz. Option Declare sorgt dafür, dass du jede Variable explizit deklarieren musst, was zur Folge hat, dass Schreibfehler bei Variablennamen nicht mehr auftreten können. Sprich du weißt irgendwo im Quelltext einer Variable einen Wert zu und möchtest darauf später zugreifen, verschreibst dich aber bei dem Zugriff. Mit der Option bekommst du einen Compiler-Fehler, ohne wird implizit ein Variant deklariert für die "Tippfehlervariable" und das Skript läuft erst zur Laufzeit auf einen Fehler.
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 09:59:25
Hallo!

Wieso verhindert das Option Declare, dass du auf den ersten Blick siehst, um welche Variable es sich handelt?

Wenn ich irgendwo ganz am Anfang des Quelltexts einen String deklariere, weiss ich weiter unten im Quelltext womöglich nicht mehr, dass die Variable ein String ist und ich muss wieder hochscrollen.
Bei einem $-Kürzel sehe ich das aber auf dem ersten Blick.

Oder sehe ich da etwas falsch?!

Dein beschriebener Nachteil bei Kürzel gibt mir natürlich auch zu bedenken.

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: MadMetzger am 17.03.08 - 10:06:16
Wenn es dir nur darum geht, solltest du über die Benennung deiner Variablen nachdenken. Beispielsweise bieten sich dafür dann Typpräfixe an, die man vergeben kann. So kannst du beispielsweise "str" für String-Variablen als Präfix nutzen.

Option Declare sollte man eigentlich immer eingeschaltet haben, da es viele Fehler verhindert bevor sie auftreten.
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 11:11:20
Stimmt! Danke, für den Tipp!

L.G.
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: MadMetzger am 17.03.08 - 11:13:06
Gerne doch... :)
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 14:14:50
Ich habe nun leider ein neues Problem.
In meinem Programm habe ich die Option gespeicherte Mitarbeiter wieder zu löschen:

Code
Sub deleteWorkerComputer(deleteWorker As String)
	Dim msg As String	
	
	Forall worker In computerWorkerList
		If worker.GetWorker = deleteWorker Then
			Delete computerWorkerList(deleteWorker)
			msg = "Mitarbeiter " & deleteWorker & " wurde aus der Datenbank gelöscht"
			Messagebox msg
		End If
	End Forall
End Sub

computerWorkerList ist eine Liste mit eigenen erstellten Objekten namens "workerComputer". In der Liste sind also bei mehreren Mitarbeitern, entsprechend mehrere Instanzen von workerComputer angelegt.

Wenn ich nun einen Mitarbeiter lösche und danach einen neuen hinzufügen möchte, kommt die Fehlermeldung "Object variable not set". Für mich ist das nicht nachvollziehbar, da ich ja nicht die ganze Liste gelöscht habe, sondern nur ein Objekt in der Liste, oder sehe ich da etwas falsch?

Hier der Code wie ein Objekt (workerComputer) in die Liste eingefügt wird:

Code
Dim newWorker As String
Dim newNumb As String
	Dim newCompRef As String

...

' Code zum Einlesen der Daten

...

Dim workerRef As New workerComputer(newWorker, newNumb, newCompRef)

Set computerWorkerList(newWorker) = workerRef

Ich hoffe, ihr könnt mir weiterhelfen, da ich erst seit einer knappen Woche in LotusScript programmiere.

Danke, im Voraus für eure Hilfe!

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: MadMetzger am 17.03.08 - 14:32:42
Nur die Fehlermeldung alleine reicht nicht aus. An was für einer Stelle kommt die Meldung denn? Interessant ist dann auch noch der Code beteiligter Methoden.
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 14:54:16
Hi MadMetzger,

Nur die Fehlermeldung alleine reicht nicht aus. An was für einer Stelle kommt die Meldung denn?

nach dem ich einen Mitarbeiter gelöscht habe und dann einen neuen anlege und die Methode workerExists aufgerufen wird bzw. eine äquivalente Methode, die nach vorhandener Nummer oder Computernamen prüft.

Code
Property Get workerExists(newWorker As String) As Boolean
	Dim msg As String
	workerExists = False	' You have to declare workerExists on this place on true, for the case computerWorkerList is empty.
								  ' In this case the forall-loop will never run.
	
	Forall worker In computerWorkerList
		If worker.GetWorker = newWorker Then
			msg = "Mitarbeiter " & newWorker & " wurde schon einem Computer zugeordnet"
			Messagebox msg
			workerExists = True
		End If
	End Forall
End Property

Zitat
Interessant ist dann auch noch der Code beteiligter Methoden.

Hier der komplette Code von der Funktion, die einen neuen Mitarbeiter anlegt:

Code
Sub generateWorkerComputer
	Dim newWorker As String
	Dim newNumb As String
	Dim newCompRef As String
	
	newWorker = Inputbox$("Bitte Mitarbeiter eingeben")
	
	If (workerExists(newWorker)) = True Then ' Controlls wether workerNumber already exists
		Exit Sub	
	End If
	
	newNumb = Inputbox$("Bitte Mitarbeiternummer eingeben")
	
	If (workerNumberExists(newNumb)) = True Then ' Controlls wether workerNumber already exists
		Exit Sub	
	End If
	
	newCompRef = Inputbox$("Bitte Computernamen eingeben")
	
	If (computerAlreadyAssigned(newCompRef)) = True Then
		Exit Sub	
	End If
	
	Dim workerRef As New workerComputer(newWorker, newNumb, newCompRef)
	
	Set computerWorkerList(newWorker) = workerRef
	
	computerWorkerList(newWorker).print
	
End Sub

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: MadMetzger am 17.03.08 - 15:15:30
Du kannst mich auch mit Markus ansprechen...  ;)

Wie sieht der Code aus, mit dem du das Anlegen und wieder Löschen durchführst. Gut wäre dann auch noch die genaue Stelle, an der der Fehler kommt. Was sagt der Debugger an der Stelle dann?

Und noch ein Hinweis in eigener Sache: Du vermischt hier meiner Meinung nach sehr stark Anwendungslogik mit Oberflächenlogik. Da solltest du drüber nachdenken manche Sachen  aus den Methoden herauszuziehen:
Code
Property Get workerExists(newWorker As String) As Boolean
	Dim msg As String
	workerExists = False	' You have to declare workerExists on this place on true, for the case computerWorkerList is empty.
								  ' In this case the forall-loop will never run.
	
	Forall worker In computerWorkerList
		If worker.GetWorker = newWorker Then
			msg = "Mitarbeiter " & newWorker & " wurde schon einem Computer zugeordnet"
			Messagebox msg
			workerExists = True
		End If
	End Forall
End Property
Hier ist es fraglich ob ein Aufrufer dieser Methode immer die Messagebox haben will. Was ist, wenn es einen Hintergrundagenten gibt, der vor Anlage eines neuen MA beispielsweise über diese Methode die Existenz eines äquivalenten Mitarbeiters überprüfen möchte. In dem Fall bekommst du in dem Agenten ein Problem.
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 16:24:39
Hi Markus,
ich habe nun herausgefunden, dass der Interpreter bei
Code
If worker.GetWorker = newWorker Then

in der Methode workerExists meckert.

Scheinbar wird der Verweis auf das gelöschte Objekt trotz der delete-Anweisung nicht vollständig gelöscht, da ich ihn noch im Debugger sehen kann, jedoch vollkommen ohne Inhalt. Der Interpreter versucht dann die Methode worker.GetWorker aufzurufen, aber da ja alle Methoden und Variablen gelöscht wurden, geht das schief.

Zitat
Wie sieht der Code aus, mit dem du das Anlegen und wieder Löschen durchführst.

Das Anlegen wird in generateWorkerComputer durchgeführt. Am Anfang werden Daten über die Inputbox abgefragt und dann anschließend ganz unten wird eine Instanz von workerComputer angelegt und in die workerComputerList hinzugefügt.

Code
	Dim workerRef As New workerComputer(newWorker, newNumb, newCompRef)
	
	Set computerWorkerList(newWorker) = workerRef
	
	computerWorkerList(newWorker).print

Das Löschen wird in der Methode deleteWorkerComputer durchgeführt (s. o.)

Die Frage ist nun, wie ich nicht nur den Inhalt eines Objekts löschen kann, sondern den Verweis zu einem Objekt selber!

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: koehlerbv am 17.03.08 - 16:31:24
Ich finde weder die Methode DeleteWorker noch die Sub Delete selbst. Aufgeführt ist nur das Delete ComputerWorkerList (also des ganzen Objekts).

Bernhard
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 16:36:13
Ich finde weder die Methode DeleteWorker noch die Sub Delete selbst.

Sorry, gemeint war deleteWorkerComputer. Hab's nun editiert.

Zitat
Aufgeführt ist nur das Delete ComputerWorkerList (also des ganzen Objekts).

Genau dieser Code löscht das Objekt.

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: koehlerbv am 17.03.08 - 16:43:10
Dafür ist das Delete ja auch da. Siehe DesignerHelp.

Bernhard
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 16:56:12
Dafür ist das Delete ja auch da. Siehe DesignerHelp.

Das Problem ist wie gesagt nur, dass eben der Verweis auf das Objekt laut dem Debugger noch in der Liste erhalten bleibt und die Abfrage nach existierender Mitarbeiter (workerExists() ) eben versucht bei dem leeren Objekt, die nicht vorhandenen Methoden (worker.getWorker) aufzurufen. Genau das löst die Fehlermeldung aus!
Das gelöschte Objekt sollte schon vollständig aus der Liste verschwinden. Wie ist das aber möglich?!

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: koehlerbv am 17.03.08 - 17:00:37
Ich bin mir sicher, Dir fehlen hier noch ganz wesentliche Basics, und vielleicht solltest Du Dich erstmal an einfacheren Dingen versuchen:
Du hast das Objekt deklariert, ergo "bleibt es auch in der Liste" und ist eben Nothing.

Bernhard
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 17:21:20
Ich bin mir sicher, Dir fehlen hier noch ganz wesentliche Basics, und vielleicht solltest Du Dich erstmal an einfacheren Dingen versuchen:

Meiner Ansicht nach ist es ein Manko der Sprache wenn das von dir beschriebene Verhalten auftritt:

Zitat
Du hast das Objekt deklariert, ergo "bleibt es auch in der Liste" und ist eben Nothing.

Dann macht die Forall-Schleife nach dem Löschen eines Objekts keinen Sinn mehr, da man mit solchen Fehlermeldungen rechnen muss.

Interessant finde ich nun, wie man diesen Fehler umgehen kann.

Irgendwelche Vorschläge?

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: koehlerbv am 17.03.08 - 17:29:13
Das ist kein Manko der Sprache (oder wir missverstehen uns alle dramatisch).
Du deklarierst ein Objekt oder eine Variable. Der Debugger zeigt Dir an, dass Du diese Deklaration gemacht hast (nicht mehr und nicht weniger). Und warum sollte die Deklaration rückgängig gemacht werden? Du willst ja später wieder darauf zugreifen (sonst würde Dich das Vorhandensein auch nicht stören).

So, wie ich das verstehe, willst Du aus einem List-Object einen Wert löschen. Dann musst Du das entsprechen tun und Dir eine entsprechende Methode dafür schreiben, aber dafür nicht gleich das komplette Objekt himmeln.

Bernhard
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 17.03.08 - 17:33:31
Gut, ich werde es wohl anders machen müssen.
Danke, für die Hilfe!

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: flaite am 17.03.08 - 17:37:06
In jeder mir bekannten Sprache (Java, JavaScript, PHP, Ruby, VisualBasic) mit Objekten kann man von einer Referenz eines Objekts in Form einer Variable, Methoden dieses Objekts aufrufen, wenn dieses null ist.
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: m3 am 17.03.08 - 17:37:54
Erase
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: koehlerbv am 17.03.08 - 17:44:44
@Axel: Das hat doch auch keiner bestritten. LotusScript ist da doch nicht anders. Nur darf man in keiner Programmiersprache dann auf Properties des Objekts zugreifen, die man gerade selbst grausam gemeuchelt hat.

@Martin: Erase wäre das Statement der Wahl, wenn es um Listen geht  ;) Das entfernt ein Listenelement und nicht gleich das ganze Objekt.

Bernhard
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: Dubidu am 18.03.08 - 08:50:07
Erase

DANKE! Nach so einer einfachen Lösung habe ich gesucht!
Darauf hätte ich aber auch selbst kommen können! :)

Liebe Grüße
Giordano
Titel: Re: ForAll-Schleife wird nicht ausgeführt
Beitrag von: MadMetzger am 18.03.08 - 08:52:38
In dem Zusammenhang empfehle ich dir noch das Lesen von "Working with Lists" (oder so ähnlich) in der Designer-Hilfe. Da steht nochmal aggregiert alles wissenswerte zu Listen mit Script...