TIA VBS Umwandlung von String zu Int mit CInt

Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Newbie,

wenn deine Aussage
...
Als ich den Code getestet habe kam ich zum Ergebnis " '2' " (Leerzeichen zur Übersicht).
...
stimmt, dann liegt hier doch der Hase im Pfeffer: " '2' " kann nicht per CInt() in eine Zahl gewandelt werden, "2" jedoch sehr wohl!!

Das Problem sind hier die Hochkommata.


Gruß, Fred
 
- wenn ich mir "TempText" wie in deinem ersten Beispiel ausgeben lasse bekomme ich als Ergebnis '2' angezeigt
bezieht sich hier drauf. Die Hochkomma hat er vermutlich von der Trace-Ausgabe und sind nicht Inhalt der Variable:
Code:
LookupText TempText, "FKT01-01_Batch_Textlist_Index", HmiRuntime.Language, Fct_Name
[COLOR="#0000FF"]HMIRuntime.Trace("Batch_Ausgabe: TempText=[COLOR="#FF0000"]'[/COLOR]" & TempText &"[COLOR="#FF0000"]'[/COLOR]" & vbCrLf)[/COLOR] 
Anz_Sollwerte = CInt(TempText)

Schade daß sich Newbie oft so ungenau ausdrückt und die wichtigen Nachfragen gar nicht oder nicht schlüssig beantwortet.
Naja, er hat ja eine Krücke zur Umgehung seines Problems gefunden. Die tatsächliche Ursache des Problems interessiert wohl nicht wirklich...

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Harald, Hallo auch allen anderen,

Es tut mir leid, dass ich mich zur Zeit nicht so oft melde, aber ich bin momentan in Schichtarbeit beim Kunden, weil dort die Anlage steht, weshalb ich mich momentan auch nicht wirklich mit dem Thema beschäftige.
Ich versuche aber immer alle Fragen so gut es geht zu beantworten und bin sehr wohl an der Klärung des Themas für die Zukunft interessiert, ich tue mich prinzipiell einfach etwas schwer mit dem Erklären der Umstände.

Zu den Fragen von Harald in #14:
- Das übergeordnete Skript wird zyklisch 1mal pro Sekunde aufgerufen, so lange ein Bit, das ich per Schaltfläche Setze gesetzt ist
- So lange dieses Bit gesetzt ist ruft das übergeordnete Skript das Skript in dem das Problem mit Cint auftritt 3mal pro Sekunde auf
- Der Index wird richtig aktualisiert, dass habe ich mir an verschiedenen Stellen vor dem LookupText per HMIRuntime ausgeben lassen
- Die Textlisten Einträge sind statisch (deswegen habe ich auch immer darauf gepocht, dass ich weis was drin steht, da ich einfach nicht wusste, dass diese auch dynamisch sein können. wurde mir so erklärt, dass die immer statisch sind)
- Ich weis ehrlich nicht wirklich wie du den Teil mit den "Arbeits"-HMI-Variablen meinst, tut mir Leid
- Den Index könnte man übergeben, aber ich verstehe nicht, wo da der Vorteil liegt. Die Funktion startet immer beim Index 10002, aber wird dann bis zum Ende des Aufrufs mehrfach verändert und ob ich das jetzt mit dem Übergabewert oder einer internen Skriptvariable mache müsste doch egal sein? sobald ich wieder im Büro bin werde ich es mal testen.
- CLng() werde ich testen sobald ich wieder im Büro bin

Das Thema mit der Ausgabe von '2' hat Harald in #22 richtig erklärt so war das gemeint. Das bezieht sich mit auf das Thema warum ich die Antwort von Helmut als hilfreichste Antwort markiert haben. Denn er hat mich auf die Idee gebracht mal nach überflüssigen Leerzeichen zu gucken, was ja durch diese Beispiel auch geht. - Deswegen hilfreichste Antwort. Und ja das Ergebnis davon gibt einen RuntimeError (zu #16). Es gab nur keinen Runtime-Error wenn ich die 2 direkt zugewiesen habe.
Code:
TempText = "2"
Anz_Sollwert = CInt(TempText)

Den Test vom rostigen Nagel kann ich leider erst wieder durchführen, wenn ich wieder im Büro bin.

Und das zum Thema Siemens-Support: ich bin jetzt seit knapp einem viertel Jahr wirklich in dieser Branche tätig und bin auch noch (in meinen Augen) ein blutiger Anfänger, deshalb vertraute ich prinzipiell erst mal auf den Siemenssupport, weil ich einfach davon ausgegangen bin, dass die für ihre eigenen Produkt doch einen mehr als qualifizierten Support haben sollten.
Ich hoffe ich dieses Mal alles beantwortet was noch offen war.
Ich geh dann mal schlafen ich schreibe sobald wie möglich zurück, falls noch jemand an dem Thema dran ist.

Grüße Newbie
 
Zuletzt bearbeitet:
Hallo Newbie,

ich beziehe mich jetzt mal auf deinen Beitrag #13 - gemäß dieses Beitrages könnte TempText demnach u.U. dem String "10002" beinhalten (...? - das wäre meine unterschwellige Frage).
Aus diesem TempText machst du nun Anz_Sollwerte was m.E. auch gelingen wird.
Nun nimmst du Anz_Sollwerte als Bezug um deine Schleife zu durchlaufen - und hier meine Frage : gibt es denn überhaupt diese Anzahl an Sollwerten ?
Ich frage das deshalb, weil deine Liste im genannten Beiträge ja z.T. große Lücken beinhaltet was auch heißen könnte, dass es hier gar keine Array-Entsprechung gibt ...

Gruß
Larry
 
Hallo Larry,

TempText nimmt den Wert ann der in der Textliste am jeweiligen Index hinterlegt ist. Da die Textlisten statisch sind und ich diese auch mehrfach geprüft habe, steht am Index 10002 immer ein Wert zwischen 0 und 10. In diesem Fall steht an dieser Stelle eine 2. Den Wert 10002 wird TempText nicht annehmen, da es lediglich der Index ist, der die Stelle zum Zugriff angibt.
Der weitere Ablauf stimmt so wie du ihn beschrieben hast.
Da es eben dann zwischen 0 und 10 Sollwerten sind, gibt es auch diese Anzahl an Sollwerten.
Dass die Textlisten so große Lücken aufweisen, wurde vom Kunden so vorgegeben.
Auf was beziehst du diese Array-Entsprechung? Auf das Format der Textliste oder die Formate der einzelnen Text/Werte, die in der Textliste hinterlegt sind?

Gruß
Newbie
 
Array-Entsprechung beziehe ich auf die Schleife deines Code-Snippets :
Code:
For LoopCount = 1 To Anz_Sollwerte       [COLOR=#008000]'blabla
      'noch unwichtig[/COLOR]
Next
Hier schreibst du zwar nicht, was in der Schleife passieren soll - i.d.R. arbeitet man hier jedoch meißt gerne mit einem Array ... ist das auch bei dir so ?
In dem Fall vielleicht nicht unwichtig : Ist es ein SPS-Array dann ist dessen Index- Null-basiert (das heißt es fängt mit Index 0 an und geht bis Arraygröße -1

Gruß
Larry
 
- Das übergeordnete Skript wird zyklisch 1mal pro Sekunde aufgerufen, so lange ein Bit, das ich per Schaltfläche Setze gesetzt ist
- So lange dieses Bit gesetzt ist ruft das übergeordnete Skript das Skript in dem das Problem mit Cint auftritt 3mal pro Sekunde auf
Ist das nötig, daß Du das Skript so oft (zyklisch!) aufrufst?? (Wie macht das das übergeordnete Skript, ein Skript 3 mal pro Sekunde aufrufen??)
Kann es sein, daß der Runtime-Error wegen CInt() sich gar nicht auf den Skriptdurchlauf bezieht, indem Deine LookupText-Rückgabe "2" ist?
Ich vermute immer noch ein Problem mit der Variablen-Aktualisierung bzw. daß bei dem fehlerhaften Skriptdurchlauf die LookupText-Parameter auf einen falschen Textlisten-Eintrag oder eine falsche Textliste zeigen.

Versuche doch mal eine Ausgabe der Variablenwerte im Fehlerfall:
Code:
On Error Resume Next
Textlist_Index = SmartTags("FKT01-01_Batch_Textlist_Index")
LookupText SmartTags("FKT01-01_Batch_TempText"), SmartTags("FKT01-01_Batch_Textlist_Index"), HMIRuntime.Language, Fct_Name
TempText = SmartTags("FKT01-01_Batch_TempText")
Anz_Sollwerte = CInt(TempText)

If Err.Number <> 0 Then
  HMIRuntime.Trace "Error #" & CStr(Err.Number) & " " & Err.Description & vbCrLf
  HMIRuntime.Trace "Err Batch_Ausgabe: Index='" & Textlist_Index & '|Text='" & TempText &"'|Zahl='" & Anz_Sollwerte &"'" & vbCrLf
  Err.Clear
  Exit Sub
End If


- Ich weis ehrlich nicht wirklich wie du den Teil mit den "Arbeits"-HMI-Variablen meinst, tut mir Leid
Ich wollte daß das Skript bzw. der LookupText-Aufruf mit eigenen HMI-Variablen (SmartTags) arbeitet, welche nicht durch irgendwas während dem Skriptablauf verändert werden. Dazu muß z.B. vor dem LookupText der Index-Wert umkopiert werden.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo miteinander,
der neue Status ist: es hat jetzt auch mit Cint funktioniert! Aber der Reihe nach um alles was zuvor geschrieben wurde noch zu behandeln.

@rostiger Nagel: Ich habe mir das Ergebnis von LookupText in ein Textfile ausgeben lassen mit folgen dem Code:

Code:
Dim File1
Dim FileWrite1

Set File1 = CreateObject("Scripting.FileSystemObject")

If Not File1.FileExists("D:\temp\Lookuptext_Ergebnis.txt") Then
 File.CreateTextFile "D:\temp\Lookuptext_Ergebnis.txt"
 HMIRuntime.Trace("Batch_Ausgabe: File erstellt" & vbCrLf)
End If

Set FileWrite1 = File1.OpenTextFile("D:\temp\Lookuptext_Ergebnis.txt",8,True)
FileWrite1.WriteLine([COLOR=#0000ff]"Anfang:"&TempText&":Ende"[/COLOR])
FileWrite1.Close
Das Ergebnis sieht dann wie folgt aus:

Anfang:2:Ende


@Larry Laffer: In der Schleife wird mit keinem Array gearbeitet. Es werden nur verschiedene Textlisteneinträge ausgelesen, um einen Zeile in einer csv-Datei mit sinnvollem Text zu füllen.

@PN/DP: Die eine Sekunde wurde bisher vom Kunden so vorgegeben, da alles einer Sollwertüberwachung/Protokollierung dient. Ich habe jetzt heute mal den Zyklus des Skripts auf 2 Sekunden hoch gesetzt und es funktioniert, ohne dass ich an der bisherigen Logik des Skripts etwas geändert habe.

Jetzt funktioniert es aber, wenn mir die Frage gestattet ist: Warum?
Ich bin immer davon ausgegangen, dass so eine Operation wie CInt maximal so 15ms benötigt, da müsste ich mit um die 300ms, die ich pro Aufruf maximal zur Verfügung stellen kann, genügend Zeit haben.
(Ist jetzt nur Off-Topic, weil mich interessiert warum es auf einmal geht)

Gruß
Newbie
 
Zuletzt bearbeitet:
Hallo Newbie,

ob Du nun das Ergebnis vom LookupText in eine Datei schreibst oder so wie in meinen Beispielen mit HMIRuntime.Trace ausgibst, macht keinen Unterschied - man sieht bei beiden Testausgaben daß das Ergebnis für CInt() absolut verträglich ist und nicht die Ursache des Runtimeerrors sein dürfte.

Eine Operation wie CInt() benötigt keine ms, sondern nur µs. Daß für das Skript 300ms Zeit wäre ist ein Trugschluß, die WinCC Runtime hat noch eine Menge mehr zu tun als nur ein (Monster-?)Skript zyklisch auszuführen.

Warum muß Dein Skript zyklisch ausgeführt werden? Ändern sich denn überhaupt Eingangsbedingungen? Schreibt das Skript auch dreimal pro Sekunde in die csv-Datei? Was schreibt es in die csv-Datei? Ein VBS-Skript mit mehr als 100 Zeilen und Schleifen ist imho nicht für zyklische Ausführung geeignet.
Ich frage mich außerdem immer noch, wie ein Skript, was selber nur jede Sekunde aufgerufen wird, ein anderes Skript dreimal pro Sekunde aufrufen kann. :confused: Oder hast Du Dich da falsch ausgedrückt?

Ich will Dir ja nicht zu nahe treten, doch so langsam verstärkt sich mein Gefühl, daß Du Dir zwar schon zutraust ein großes Skript zu schreiben, andererseits aber zu wenig Ahnung von VBS hast, um da mal erfolgreich eine gezielte Fehleranalyse zu machen. Vielleicht sind deshalb Deine Antworten kaum hilfreich und oft nicht eindeutig? Auf meine Vermutung daß falsche Variablenwerte verarbeitet werden, bist Du gar nicht eingegangen.


PS: Bei Deiner Behelfs-Krücke in #8: Wofür ist da die For-Schleife? Die frisst nur unnötig Zeit.

Harald
 
Ich würde Harald hier uneingeschränkt zustimmen. Es wäre wirklich hilfreich, ein bißchen mehr über dein Gesamt-Vorhaben zu wissen und wie du es aufgebaut hast. Du brauchst auch keine Angst haben, hier Geheimnisse zu offenbaren - an den Antworten kannst du erkennen, dass die grundsätzliche Vorgehensweise für uns nicht unbekannt ist ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

Zum Thema mit der Textdatei: Ich hab mir auch gedacht, dass eigentlich keinen Unterschied macht, ob nun eine Ausgabe in Tracefenster oder in eine Textdatei erfolgt. Aber da rostiger Nagel mehrfach gefragt hat, wollte ich es einfach mal ausprobieren und die Ergebnisse teilen.

Ich will Dir ja nicht zu nahe treten, doch so langsam verstärkt sich mein Gefühl, daß Du Dir zwar schon zutraust ein großes Skript zu schreiben, andererseits aber zu wenig Ahnung von VBS hast, um da mal erfolgreich eine gezielte Fehleranalyse zu machen. Vielleicht sind deshalb Deine Antworten kaum hilfreich und oft nicht eindeutig? Auf meine Vermutung daß falsche Variablenwerte verarbeitet werden, bist Du gar nicht eingegangen.
Ist so eigentlich ziemlich richtig. Ich habe schon mal größere Programme geschrieben allerdings programmiere ich normalerweise MS-Anwendungen in C# oder schreibe kleinere SPS-Programme. Also es ist schon so, dass ich mir das zutraue und ich auch schon programmiert habe, allerdings jetzt das erste Mal in VBS. Und vor allem das erste mal ohne einen vernünftigen Debugger mit dem ich während der Laufzeit meines Programms Schritt für Schritt betrachten kann. Wie in einem früheren Post schon mal erwähnt ich bin noch neu in der Branche.
Zu den Variablenwerten kann ich nur sagen, dass ich mir jede Variable vor und nach dem LookupText per Trace ausgeben lasse und immer die Werte darin stehen, die ich auch erwarte, dass sie da drin stehen.

Beschreibung des gesamten Projekts:
Mein Kunde produziert Fertiganlagen in Serie, weshalb Namensgebung und Funktionen einheitlich zu halten sind. Er möchte jetzt für die neue Generation mit einem Batchreport ausstatten.
Der Batchreport soll mit dem Start eines Rezepts für eine Funktionsgruppe beginnen. Es werden ein paar Grundinformationen in einen Header eingetragen übliches BlaBla Rezeptname, Datum,, etc.. Während das Rezept läuft sollen alle Sollwerte einer Funktion aufgezeichnet werden, sobald diese aktiv ist. Außerdem sollen auch die Änderungen der Sollwerte mitgeloggt werden, solange die Funktion und das Rezept aktiv sind. Die Funktionen haben immer die gleiche Nummer für jede Funktionsgruppe (FG1 Dispergieren ist FktNr 5 -> FKT01-01-05, FG2 Dispergieren ist FktNr5 -> FKT02-01-05). Sie möchte jetzt das ich für FKT01 ein Skript schreibe, welche diese Aufgabe erfüllt und Sie einfach per Copy-Paste für ihre anderen Funktionsgruppen verwenden können.

Ich mache das jetzt momentan so:
Über einen Variablentrigger auf dem Rezeptstart setze ich ein Bit "Batch_active". Direkt am Anfang meines zyklischen Skripts wir mit "if" dieses bit abgefragt. Sollte das Bit nicht gesetzt sein wird in dem Skript kein Code ausgeführt. Im Hauptskript läuft ein Counter mit, damit ich feststellen kann, im wievielten Aufruf ich mich befinde. Denn beim ersten Aufruf werden einmalige Sachen in die Csv geschrieben, wie Header und Randinformationen zum Batch: Rezeptname, Sollmenge, Datum, usw.
Sobald dieser Teil in der csv-Datei steht, beginnt der Teil, der immer zyklisch überwacht werden soll. Ich prüfe bei jedem Aufruf, ob sich der User verändert hat, um es gegebenenfalls in die csv zu schreiben. Außerdem überwache ich alle Funktionen, die zu diesem Rezept bzw. dieser Funktionsgruppe gehören. Eine Funktionsgruppe hat laut Kunde maximal 99 Funktionen und diese Funktionen haben in jeder Gruppe die gleiche Nummer(z.B. Funktionsgruppe1-Dispergieren -> FKT01_01_05 als Variablenpräfix, Funktionsgruppe4-Dispergierenm-> FKT04_01_05). Da die Batch-Protokollierung für alle Funktionsgruppen einsetzbar sein soll, muss ich immer mit den maximal 99 Funktionen rechnen, weis aber nie welche wirklich verwendet werden. Hinzu kommt, dass die Funktion eigentlich nie nummerisch geordnet vorkommen sonder auch öfters mal eine weggelassen wird (z.B. Funktionsgruppe1 hat die Funktionen 01, 02, 05,10,20,66).
Über ein DWord, das für jede Funktion ander selben Stelle der entsprechenden HMI-Variablenstruktur steht und in der SPS immer gleich gebildet wird, kann ich den Status der einzelnen Funktionen auslesen. Ist eine Funktion aktiv beginnt der Sollwertvergleich, das Skript mit CInt um das es zuvor immer ging. (Deswegen wird das Skript momentan ca. 3 mal pro Sekunde aufgerufen, da ich pro Hauptskriptaufruf momentan mit 3 aktiven Funktionen teste). In dem Skript mit CInt hole ich mir die wichtigsten Werte zur Funktion aus einer Textliste: Anzahl von Sollwerten und Name der Funktion. Sollte sich im Vergleich zum letzten Zyklus ein Sollwert geändert haben, wird der neue Sollwert in die csv-Datei geschrieben. Um diese nun mit Sinnvollem Text zu füllen, lies ich in der gleichen Textliste die entsprechende Texte aus.

Also grob zusammen gefasst: Zum Rezeptstart wird der Batch-Report gestartet. Am Anfang stehen einige Grundinformationen zum Batch. Ab dann muss jede Änderung des Users erfasst werden. Außerdem muss mitgeloggt werden, wenn sich ein Sollwert einer laufenden Funktion ändert/ er vom Bediener geändert wird. Dazu soll noch im Batch zu erkennen sein, wenn das Rezept pausiert wurde oder Bediener von Hand Funktionen der Funktionsgruppe übersprungen hat.
Ich muss also ständig prüfen, ob sich irgendetwas im Umfeld der Funktionsgruppe verändert, weshalb ich ein zyklisch Skript verwende, weil ich mir nix anderes vorstellen konnte.

Ich hoffe ich habe alles für euch verständlich zusammen gefasst.

Gruß
Newbie
 
Darf ich mal fragen auf welcher Umgebung deine Anwendung läuft,
die Panels von Siemens, sind für Ihre Leistungsschwäche bekannt.
Zum anderen ist es gewährleistet das die Datensätze aus den Rezepturen
vollständig geladen sind und die zu überprüfenden Variablen aktuell sind?
 
Zurück
Oben