+1 800 256 3608 (toll-free in North America) or +49 7531 90 60 10| service@combit.com

"Arrays" in Labelprojekt?


(Guest) #1

Hallo zusammen!

Ich habe unter LL15/Delphi/VCL ein Labelprojekt, in dem ich Etiketten für “Teile” drucke. Jedes dieser Teile kann eine (prinzipiell beliebige) Anzahl von Anbauteilen haben. Unsere User möchten nun einige Daten (Länge, Artikelnummer) dieser Anbauteile auf dem Etikett des zugehörigen “Owner”-Teils sehen. Dazu fallen mir verschiedene Ansätze ein, die alle ihre Nachteile haben:
[list=1][]Ich beschränke die Anzahl auf bspw. 10 und definiere Variablen a la Anbauteil1.Laenge bis Anbauteil10.Laenge, Anbauteil1.ArtikelNr bis Anbauteil10.ArtikelNr… Nachteile: Fixe Anzahl, die nahezu immer zu groß (==> Prüfungen, ob Variable leer) oder zu klein (==> Informationsverlust) ist. Außerdem müssen die Einstellungen im Designer für alle zusammengehörenden Variablen redundant gepflegt werden.
[
]Ich definiere “Sammelvariablen” a la Anbauteile.Laengen, Anbauteile.ArtikelNummern. Hier stellt sich die Frage, wo ich hier im Designer z.B. Zahlenformatierungen hinterlege.[/list]
Bisher habe ich Variante 2 probiert, wobei ich z.B. aus den Artikeln AAA, BBB und CCC eine Variable Anbauteile.ArtikelNummern mit Contents AAA/BBB/CCC bastele, etwa so:

sDelimiter := MyL15.LlPrintGetProjectParameter(...); sArtikelNrn := konkateniere alle Artikelnummer, getrennt durch sDelimiter MyL15.LlDefineVariableExt('Anbauteile.ArtikelNummern', sArtikelNrn, LL_TEXT);

Gibt’s da eine elegantere Möglichkeit? Mir schwebt da etwas ähnliches wie die Control Arrays in Visual Basic vor.


(Guest) #2

Ich versuch’s nochmal konkreter zu beschreiben:

Ich hätte gern auf jedem Etikett eine Teilmaßkette gedruckt, z.B.

Dabei ist die Länge der Kette von Etikett zu Etikett unterschiedlich. Außerdem wäre schön, wenn der Ersteller des Berichts im LL-Designer die Darstellung der Einzelmaße beeinflussen kann, z.B. die Anzahl der Nachkommastellen und ob ein “mm” hinter die Maßangabe kommt oder nicht:

Dazu muss ich die einzelnen Maße wohl als LL_NUMERIC übergeben und nicht schon als programmatisch zusammengefassten String.

Wie würdet ihr das angehen?


(Guest) #3

Ganz elegant: Du benutzt (.NET, Delphi) eine eigene benutzerdefinierte LL-Funktion, die Du z.B. “ConcatMeasures$” nennst, dann kann der Benutzer die gewünschte Formatierung in den Parametern angeben, d.h. im Etikett schreibt der Benutzer dann beispielsweise:

ConcatMeasures$("###.#mm",";")

und Du mußt die Funktion “nur” noch bauen und in dieser die Unterwerte direkt entsprechend formatiert zusammenkleistern und das Ergebnis an LL zurückgeben.

Zumindest wäre das die Methode meine Wahl. Nahtlos und flexibel. Nur über den Format-String (und denssen Nachbearbeitung bei Dir) mußt Du Dir noch Gedanken machen…

Paulchen


(Guest) #4

Danke für die Antwort. Ich probier das gerade aus.

[quote=Paul Schmidt]ConcatMeasures$("###.#mm",";")

und Du mußt die Funktion “nur” noch bauen und in dieser die Unterwerte direkt entsprechend formatiert zusammenkleistern und das Ergebnis an LL zurückgeben.[/quote]
Gibt’s da eine Möglichkeit, die Formatierung per LL-API machen zu lassen? Ich kann das natürlich mit den Delphi-eigenen Routinen machen, aber mit einer LL-Routine wäre gewährleistet, dass der Endbenutzer nur eine Formatstring-Syntax lernen muss.

Ich nehme an, das ^^ heißt “nein”. :slight_smile:


(Guest) #5

Doch, klar geht das…

Prinzip:

HLLJOB hExprJob = LlJobOpen(nLanguage | LL_JOBOPENFLAG_NOLLXPRELOAD)
HLLEXPR hExpr = LlExprParse(hExprJob ,“fstr$(Wert,”’ + ARG[1] + “’)”)
sResult = “”
for each val in values
LlDefineVariable(hExprJob,“Wert”,val)
LlExprEvaluate(hExprJob,hExpr,sThisResult)
sResult = (sResult.IsEmpty() ? “” : ARG[2]) + sThisResult
LlExprFree(hExprJob,hExpr)
LlJobClose(hExprJob)
return(sResult)

So sollte es funktonieren, und der Benutzer kann dann die Format-Anweisung von FStr$() benutzen. (Den LL-Job solltest Du vielleicht aus Performance-Gründen cachen, aber sonst…)

Sorry für Nicht-Delphi-Syntax, das ist gerade eigens-erfundener Pseudo-Code :wink:

Paulchen


(Guest) #6

[quote=Paul Schmidt]Doch, klar geht das…

Prinzip:

HLLJOB hExprJob = LlJobOpen(nLanguage | LL_JOBOPENFLAG_NOLLXPRELOAD)
HLLEXPR hExpr = LlExprParse(hExprJob ,“fstr$(Wert,”’ + ARG[1] + “’)”)
sResult = “”
for each val in values
LlDefineVariable(hExprJob,“Wert”,val)
LlExprEvaluate(hExprJob,hExpr,sThisResult)
sResult = (sResult.IsEmpty() ? “” : ARG[2]) + sThisResult
LlExprFree(hExprJob,hExpr)
LlJobClose(hExprJob)
return(sResult)

So sollte es funktonieren, und der Benutzer kann dann die Format-Anweisung von FStr$() benutzen. (Den LL-Job solltest Du vielleicht aus Performance-Gründen cachen, aber sonst…)
[/quote]
Danke, probier ich nachher mal.

[quote=Paul Schmidt]Sorry für Nicht-Delphi-Syntax, das ist gerade eigens-erfundener Pseudo-Code :wink:
[/quote]
Als Delphi-Programmierer lernt man irgendwann, mit C, C++ und WinAPI-Style-Code klarzukommen. :wink:


(Guest) #7

Hmmm, ich hab’s jetzt mal “delphisiert” und ein paar Aufrufe umgedreht. Der Code in der Schleife schaut jetzt ungefähr so aus:

s := FloatToStr(DasAktuelleMass); nRet := LlDefineVariableExt(hExprJob, 'Wert', PChar(s), LL_NUMERIC, nil); s := 'Fstr$(Wert,"' + AFormatString + '")'; hExpr := LlExprParse(hExprJob, PChar(s), False); nRet := LlExprEvaluate(hExprJob, hExpr, sThisResult, SizeOf(sThisResult)); LlExprFree(hExprJob, hExpr);
wobei s und AFormatString Delphi-Strings sind. (In Delphi werden Strings mit einfachen Hochkommas begrenzt.)
Das liefert immer ‘******’ als Ergebnis (sThisResult), obwohl ich keinen fehlgeschlagenen Funktionsaufruf finde. Woran kann das denn liegen?


(Guest) #8

fstr$() liefert Sternchen, wenn der Wert zu groß ist für den Format-String.


(Guest) #9

Ja, weil ich den Formatstring vergurkt haben. :-/

Ich hab jetzt in der VCL-Komponente noch einen (etwas knapp dokumentierten ;-)) Wrapper um die LlExpr*-Routinen gefunden, so dass der Formatierungscode noch etwas übersichtlicher geworden ist:

LL.LlDefineVariableExt('Wert', DasAktuelleMass, LL_NUMERIC); Evaluator := TLl15ExprEvaluator.Create(LL, 'Fstr$(Wert,"' + AFormatString + '")', False); try if Evaluator.ErrorValue = 0 then // benutze Evaluator.Result finally Evaluator.Free; end;

Danke nochmal, Paulchen!


(Guest) #10

Update, zur Warnung für andere LL-Newbies:
Paulchen hat nicht umsonst einen Extra-Job (HLLJOB hExprJob) angelegt. Wenn man das unterlässt, entstehen teilweise unschöne Effekte im Formelassistenten (auch wenn nachher der designte Bericht prinzipiell passt). Als VCL-User habe ich daher noch eine (gecachete) TL15_-Instanz EvaluatorLL angelegt und als Parent für den TLl15ExprEvaluator genommen.


(Guest) #11

My middle name “Experienced LL user” :wink:

Aber was für “seltsame Effekte” denn? Ich wollte schlicht verhindern, daß die Variable “Wert” plötzlich im Funktionsassistenten zur Verfügung steht, da es kein “LlDeleteVariable()” gibt.

Paulchen


(Guest) #12

[quote=Paul Schmidt]My middle name “Experienced LL user” :wink:

Aber was für “seltsame Effekte” denn? Ich wollte schlicht verhindern, daß die Variable “Wert” plötzlich im Funktionsassistenten zur Verfügung steht, da es kein “LlDeleteVariable()” gibt.[/quote]
Wenn man den Berichtsdesigner startet, wird die Formel in der Layout-Vorschau noch richtig interpretiert. Wenn man sich dann aber bis zum Formelassistenten für dieses Feld durchklickt, steht in der Vorschauzeile eine Fehlermeldung - spätestens, sobald man an der Formel irgendeine Kleinigkeit ändert. Danach wird sie auch in der Layout-Vorschau nicht mehr angezeigt.

WIMRE tritt das sogar dann auf, wenn man gar keine Variable verwendet, sondern die zu formatierende Zahl schon delphiseitig in den Fstr$-Ausdruck einbaut.