Batch Input ideal umsetzen

Alles rund um die Sprache ABAP®: Funktionsbausteine, Listen, ALV
8 Beiträge • Seite 1 von 1
8 Beiträge Seite 1 von 1

Batch Input ideal umsetzen

Beitrag von ralf.wenzel (Top Expert / 3776 / 176 / 262 ) »
Moin,

ich soll einen Batch-Input umgestalten, damit Änderungen und Erweiterungen einfacher werden. Ich ringe mit mir zwischen einer Klassenkonstruktion, die den Batch-Input in irgendeiner Weise atomarisiert (oder sagt man "atomisiert"? ;) ) und verschiedenen anderen Möglichkeiten.

Daher mal die Frage an die Kollegen: Welche Erfahrungen habt ihr gemacht? Wie setzt ihr Batch-Input-Lösungen um?

Und an die Bedenkenträger: Eine Abschaffung kommt aus Prozesssicht leider nicht in Frage.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: Batch Input ideal umsetzen

Beitrag von a-dead-trousers (Top Expert / 4274 / 213 / 1140 ) »
hi!

In wie weit "Änderungen und Erweiterungen"? Nur betreffend der vorhandenen Felder und deren Werten oder auch wenn z.B. neue Felder in den Dynpros hinzukommen?
Bei ersterem wüsste ich jetzt nicht wie man da bei einem bestehenden Batch-Input, außer durch Umbau eines bestehenden (aufgezeichneten) Ablaufs, irgendwas verbessern könnte. Man müsste nur entsprechende Felder mit anderen Werten versorgen (z.B. über einen Selecton-Screen oder einer Daten-Datei)
Bei zweiterem wirds schon hakeliger: Wie die beteiligten Dynpros am Besten auslesen und notwendige Felder ermitteln? IMPORT DYNPRO funktioniert zwar immer, aber aus der internen Darstellung die notwendigen Informationen herauslesen ist nicht so leicht. Ob die RS_* Bausteine auch für "normale" Dynpros funktionieren weiß ich leider nicht. Ich hab die bislang nur bei Selection-Screens eingesetzt.
Die Königklasse, meines Erachtens, wäre dann auch noch auf neue Dynpros im Ablauf reagieren zu können. Wobei ich aber keine Ahnung habe wie man das 100%ig sicherstellen könnte. Klar gibt es die "Folgedynpros" aber die Applikation muss die ja nicht verwenden und kann einfach mit CALL SCREEN arbeiten.

So, mal meine Gedanken zu dem Thema. Ich weiß leider nicht wieviel du davon selber schon herausgefunden hast. Alles in Allem sehe ich im Moment keine, für alle möglichen Anwendungsfälle, brauchbare Lösung.

Zu deiner Frage: Wie setzt ihr Batch-Input-Lösungen um?

Meist lasse ich mir eine Transaktion aufzeichnen. Speichere mir das Ergebnis als Programm ab und baue es dann so um, dass es brauchbar (vulgo flexibel) einsetzbar ist. Leider verhindert die Natur der Sache IMHO eine bessere Lösung, da sich die Transaktionen eingentlich mit jedem Patch-/Release-/EnhancementPack-Wechsel ändern könnten.

Was die "Bedenkenträger" betrifft, kann ich nur sagen, dass Batch-Input durchaus seine Berechtigung hat und ich auch deswegen immer zweimal überlege Controls und ALV-Grid im Speziellen einzusetzen.

lg ADT

EDIT: Möglich das vielleicht eine Analyse des Transaktionsrecorders weiterhilft. Irgendwoher muss ja auch der seine Informationen beziehen.
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Batch Input ideal umsetzen

Beitrag von ralf.wenzel (Top Expert / 3776 / 176 / 262 ) »
Moin. Mit Änderungen und Erweiterungen meine ich z. B.: Bei Erfüllung bestimmter Bedingungen in den Dynprodaten Verwendung eines anderen OK-Codes und "Abzweigen" in eine andere Dynprofolge. Die müsste auch wieder "hart" codiert werden, schon klar. Ich möchte dabei aber nicht die Stabilität des Gesamtsystems gefährden. Man könnte z. B. derart modularisieren, dass jedes Dynpro eine eigene Modularisierungseinheit darstellt, das könnte deutlich besseren Überblick erzeugen (das ist eine Mutmaßung!). Und das Einschieben einer "Weiche" wie beschrieben würde die Übersichtlichkeit nicht gefährden.

Ich will halt kein lineares Coding verwenden, wie der Transaktionsrecorder es erzeugt -- weil das recht unübersichtlich ist. Beispiel VA01: Das ist alles noch einfach, wenn man einen Auftrag anlegt. Wenn man aber alternativ einen Auftrag auf Basis eines anderen Beleges anlegt hat man einen gigantischen CASE, der das Coding dermaßen zerschneidet, dass man echt aufpassen muss, wo genau im Coding man sich befindet, wenn man etwas ändert.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Batch Input ideal umsetzen

Beitrag von ewx (Top Expert / 4784 / 294 / 628 ) »
ralf.wenzel hat geschrieben:[...]Und das Einschieben einer "Weiche" wie beschrieben würde die Übersichtlichkeit nicht gefährden.
Aber es wird die Stabilität des BI gefährden!
ralf.wenzel hat geschrieben:Ich will halt kein lineares Coding verwenden, wie der Transaktionsrecorder es erzeugt -- weil das recht unübersichtlich ist.
Ich könnte mir vorstellen, dass man es auf Dynpro-Ebene herunterbricht.
Problem beim BI sind IMHO nicht die Einheiten, sondern die Verbindung zwischen den Einheiten (OK-Code).
Wenn du ein neues Dynpro rein programmierst, kannst du nicht sicher sein, dass durch nach dem Rücksprung aus dem Dynpro wieder auf dem gleichen Dynpro landest, wie vorher. Es ist also gut für die Integrität, dass alles zusammen ist. Klar, bei Änderungen wird es kompliziert.
vielleicht ist eine Befüllung der Dynpros in eigenen Modulen sinnvoll sowie zusätzlich die Steuerung zwischen den Dynpros?
[/code]start(VA01).
ok_code (ENTER).
va01_uebersicht(bdc_cursor = 'rv45a-posnr' ).
ok_code( okcode_positionsdetail ).
va01_positionsdetail( Input = my_input_data ).
[/code]
Eine gute Kommentierung des Codes ist evtl. einfacher...?
ralf.wenzel hat geschrieben:[...]dass man echt aufpassen muss, wo genau im Coding man sich befindet, wenn man etwas ändert.
Komisch, das geht mir immer so beim Programmieren... :P

Re: Batch Input ideal umsetzen

Beitrag von black_adept (Top Expert / 3943 / 105 / 886 ) »
Hallo Ralf,

das Stichwort lautet "Modularisierung" und nicht "Atomisierung".

Wenn man einen BI verwendet hat man ja meist den Auftrag gleichartige Sachen mit verschiedenen Eingabedaten zu machen. Aber dein Problem ist eben, dass diese Sachen nicht gleichartig genug sind, aber ähnlich genug um nicht 1000 Programme anpassen zu müssen, wenn sich irgendetwas grundlegendes geändert hat.

Bleiben wir mal bei deinem Beispiel: Auftragsanlage.
Was du hier benötigst sind feste Punkte in der Abfolge, die du als Anker für einen Modulbaukasten benötigst.
In der VA01 könnte das z.B. das mit den Kopfdaten gefüllte Übersichtsbild der VA01 sein. Tabreiter ganz links ist ausgewählt und der Cursor in der obersten Positionszeile ganz links positioniert

Und jetzt beginnt die Modularisierung:
Um zu diesem Fixpunkt zu kommen kannst du dir jetzt 2 "Einstiegsmodule" bauen. Eins für die "normale" VA01 und eins für "Auftragsanlage mit Vorlagebeleg"

Danach wirst du evtl. diverse Positionen bearbeiten wollen. Je nach dem was du vorhast wäre eine übliche Vorgehensweise für eine hier einsetzende Modularisierung:
Modul anfang
- Positioniere die von dir zu bearbeitende Zeile ganz oben und setze den Cursor auf die Zeile
- durchlaufe eine Dynprofolge um die Daten zu setzen, die du benötigst
- verwende ein paar Kommandos um zu deinem Fixpunkt zurück zu gelangen.
Modul ende

Und am Ende wirst du noch ein Exit-Modul benötigen mit dem du deine Änderungen speichern kannst.

Jedes deiner Module kann wenn nötig auch wieder modular aufgebaut sein, wenn du dort innere Fixpunkte definieren kannst. Beispiel hier: Für eine Position sollst du eine Partnerrolle einfügen, aber manchmal zusätzlich auch noch ein weiteres Feld füllen. Dann wäre der Fixpunkt hier der Dynpro nach dem Einfügen der Partnerrolle. In einem Fall würdest du ein leeres Modul durchlaufen, im anderen ein Modul das von hier aus das weitere Feld füllt und danach wieder zu dem inneren Fixpunkt zurückkehrt .

Nachteil dieser Vorgehensweise: Es werden bestimmt einige Dynpros zu viel durchlaufen um nach jedem Modularisierungsschritt zu dem definierten Fixpunkt zurück zu kommen. Jeder fähige Programmierer würde solche überflüssigen Schritte in seinem hart verdrahteten BI entsorgen - aber wenn du eine flexible und wartbare Lösung haben willst ist das halt der Preis.

Vorteil: Du kannst das richtig schon klassenbasiert machen. Deine Modularisierungseinheiten haben einfach einen Rückgabeparameter vom Typ der BI-Tabelle und du rufst dann im Coding nur deine Module der Reihe nach auf und appendierst die Rückgabewerde der Reihe nach in deinen Gesamt-BI-Ablauf

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
ralf.wenzel

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Batch Input ideal umsetzen

Beitrag von a-dead-trousers (Top Expert / 4274 / 213 / 1140 ) »
Die "unnötig" durchlaufenen Dynpros könnten dadurch vermieden werden, indem die Modularisierungseinheiten am Ende zusätzlich noch die aktuelle Dynproposition zurückgeben. Das nachfolgende Modul muss sich dann um einen effizienten Wechsel zu seinem Einsprungspunkt kümmern. Oder aber es gibt zusätzliche "Navigationsmodule" die sich um derartige Angelegenheiten kümmern.
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Batch Input ideal umsetzen

Beitrag von ralf.wenzel (Top Expert / 3776 / 176 / 262 ) »
Also, ich hab heute Nacht (ich konnte nicht schlafen) darüber mal intensiv nachgedacht. Es wäre vielleicht ganz gut, ein Dynpro mit dem OK-Code des vorherigen aufzurufen, weil ich dann ja weiß, wo es hingeht. Beispiel:

Dynpro 1.

OkCode 1, Dynpro 2.

Okcode 2, Dynpro 3

etc.

Ich bastel mir das mal zusammen und werde das Coding hier veröffentlichen, vielleicht ist das ne gute Anregung für andere. Erstmal vielen Dank an die Diskutanten.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Batch Input ideal umsetzen

Beitrag von horst1959 (ForumUser / 20 / 0 / 0 ) »
Hallo

Also mal mein Vorschlag, falls jemand Lust hat das zu lesen ....

Eine Klasse und ein paar Makros und der Aufruf z. B. so

data : o_new_batch type ref to zcl_new_batchinput,
my_val type bdc_fval.


data : l_mappe type apq_grpn,
error type sysubrc,
......


o_new_batch = zcl_new_batchinput=>create( ).

Mit Mappe für SM35

if p_simu = abap_false.
error = o_new_batch->mappe_make( e_name = g_mappe e_keep = abap_false ). " löschen
else.
error = o_new_batch->mappe_make( e_name = g_mappe e_keep = abap_true ).
endif.

Daten reingeben

eventuell den Nutzer setzen

call method o_new_batch->change_user
exporting
e_user = 'NUTZER_XXX'.

ein Beispiel

add_frame 'SAPLCOKO1' '0110' '/00'.
add_value 'CAUFVD-AUFNR' <fs_table>-aufnr.
add_value 'R62CLORD-FLG_OVIEW' abap_on.
add_frame 'SAPLCOKO1' '0115' '=KOAL'.
add_frame 'SAPLCOKO1' '0115' '=BU'.
add_value 'CAUFVD-CY_SEQNR' <fs_table>-cy_seqnr.
call method o_new_batch->do_it
exporting
e_trans = 'CO02'
e_syncron = abap_true " Synchron
e_errmap = abap_true " Mappe in Fehlerfall
e_display = l_visi " Sichtbar abspielen 'X' oder Space
importing
i_error = error.

noch ein Beispiel

*----- Fauf geht noch zu schieben
if fauf_closed = abap_false
and not l_datum is initial.
add_frame 'SAPLCOKO1' '0110' '/00'.
add_value 'CAUFVD-AUFNR' <lfs_abmeld>-aufnr.
*----- Kapaglättung
if l_planart = 'KAPA'.
add_frame 'SAPLCOKO1' '0115' '=TERM'.
add_value 'CAUFVD-TERKZ' '3'.
write l_datum to my_val dd/mm/yyyy. "Datum
add_value 'CAUFVD-GLTRP' my_val.
endif.
*----- Umterminierung
if l_planart = 'TERM'.
add_frame 'SAPLCOKO1' '0115' '=TPAR'.
add_frame 'SAPLCOZF' '0200' '=ENT1'.
add_value 'TCX00-STVERG' l_anztage.
add_frame 'SAPLCOKO1' '0115' '=ENT1'.
write l_datum to my_val dd/mm/yyyy. "Datum
add_value 'CAUFVD-GLTRP' my_val.
clear my_val.
add_value 'CAUFVD-GSTRP' my_val.
add_value 'CAUFVD-TERKZ' '2'.
endif.
add_frame 'SAPLCOKO1' '0115' '=BU'.
call method o_new_batch->do_it
exporting
e_trans = 'CO02'
e_syncron = abap_true
e_errmap = abap_false
e_display = abap_false
importing
i_error = l_errormap.
endif.


Und immer fein die Mappe am Ende zumache, da sie im Fehlerfall automatisch erstellt wird !

error = o_new_batch->mappe_close( ).

Und dann einfach abspielen

call method o_new_batch->mappe_play( e_name = l_mappe ).


Die Klasse selber.


*&---------------------------------------------------------------------*
*& Include ZCL_NEW_BATCHINPUT *
*&---------------------------------------------------------------------*


* Makro - Beispiele
*
* define bdc_add_frame.
* call method o_batch->append_mappe
* exporting
* e_okcode = &1
* e_progra = &2
* e_dynpro = &3
* importing
* i_error = error.
* end-of-definition.
*
* define bdc_add_value.
* my_val = &2.
* call method o_batch->append_mappe
* exporting
* e_fnam = &1
* e_fval = my_val
* importing
* i_error = error.
* end-of-definition.

*----------------------------------------------------------------------*
* CLASS zcl_new_batchinput DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class zcl_new_batchinput definition.

public section.

types i_self type ref to zcl_new_batchinput.
types ty_bdcdata type standard table of bdcdata.
types boolean(1) type c.
constants : true type boolean value 'X',
false type boolean value space.
data : ta_bdcdata type ty_bdcdata,
wa_bdcdata type line of ty_bdcdata.

methods constructor.

class-methods create returning value(ref) type i_self.

methods change_user importing e_user type syuname.

methods data_input importing e_trans type sytcode optional
e_okcode type bdc_fval optional
e_cursor type bdc_fval optional
e_progra type bdc_prog optional
e_dynpro type bdc_dynr optional
e_fnam type fnam_____4 optional
e_fval type any optional
exporting i_error type sysubrc.

methods do_it importing e_trans type sytcode
e_display type boolean optional
e_errmap type boolean optional
e_syncron type boolean optional
exporting i_error type sysubrc.

methods mappe_make importing e_name type apq_grpn
e_keep type boolean optional
returning value(i_error) type sysubrc.
methods mappe_openstatus exporting i_open type boolean.
methods mappe_aktivstatus importing e_name type apq_grpn
returning value(i_aktiv) type boolean.
methods mappe_close returning value(i_error) type sysubrc.
methods mappe_play importing e_name type apq_grpn.

private section.

data : make_mappe type boolean,
mappe_is_open type boolean,
anz_error type i,
my_value type bdc_fval,
my_display(1) type c,
my_datum type sydatum.

data : bi_qid type apq_quid, "#EC NEEDED
bi_mappe type apq_grpn, "#EC *
bi_user type apq_mapn. "#EC NEEDED

methods mappe_open importing e_name type apq_grpn
e_keep type boolean optional
exporting i_error type sysubrc. "#EC *

endclass. "zcl_new_batchinput DEFINITION


*----------------------------------------------------------------------*
* CLASS zcl_new_batchinput IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class zcl_new_batchinput implementation.


method constructor.
bi_user = sy-uname.
my_datum = sy-datum.
free ta_bdcdata.
clear : wa_bdcdata, anz_error, mappe_is_open, make_mappe.
endmethod. "constructor


method create.
create object ref.
endmethod. "create

method change_user.
if not e_user is initial.
bi_user = e_user.
endif.
endmethod. "change_user


method data_input.
define data_input.
clear wa_bdcdata.
wa_bdcdata-program = &1.
wa_bdcdata-dynpro = &2.
if not &2 is initial.
wa_bdcdata-dynbegin = 'X'.
endif.
wa_bdcdata-fnam = &3.
wa_bdcdata-fval = &4.
append wa_bdcdata to ta_bdcdata.
i_error = sy-subrc.
end-of-definition.
if not e_progra is initial.
data : my_progra type bdc_prog.
my_progra = e_progra.
translate my_progra to upper case. "#EC TRANSLANG
data_input my_progra e_dynpro '' ''.
endif.
if not e_cursor is initial.
data_input '' '' 'BDC_CURSOR' e_cursor.
endif.
if not e_okcode is initial.
data_input '' '' 'BDC_OKCODE' e_okcode.
endif.
if not e_fnam is initial.
data : my_fnam type fnam_____4.
my_fnam = e_fnam.
my_value = e_fval.
translate my_fnam to upper case. "#EC TRANSLANG
data_input '' '' my_fnam my_value.
endif.
if not e_trans is initial.
call function 'BDC_INSERT'
exporting
tcode = e_trans
tables
dynprotab = ta_bdcdata
exceptions
internal_error = 1
not_open = 2
queue_error = 3
tcode_invalid = 4
printing_invalid = 5
posting_invalid = 6
others = 7.
i_error = sy-subrc.
if i_error = 0.
free ta_bdcdata.
endif.
endif.
endmethod. "data_input


method do_it.
data : fehler type sysubrc, "#EC NEEDED
modus(1) type c.
i_error = 1.
check not e_trans is initial.
if make_mappe = false.
if e_syncron is initial.
modus = 'A'. " Asynchron
else.
modus = 'S'. " Synchron
endif.
if sy-batch = false and e_display = true.
my_display = 'A'.
else.
my_display = 'N'.
endif.
call transaction e_trans using ta_bdcdata
mode my_display
update modus. " Synchron
i_error = sy-subrc.
if modus = 'S'
and i_error = 0.
commit work and wait.
if sy-subrc <> 0.
i_error = sy-subrc.
endif.
endif.
if i_error <> 0.
if e_errmap = true.
anz_error = anz_error + 1.
call method me->data_input
exporting
e_trans = e_trans
importing
i_error = fehler. " keine Rückgabe auf P_ERROR! Fehler
" stehen lassen
endif.
endif.
else.
call method me->data_input
exporting
e_trans = e_trans
importing
i_error = i_error.
endif.
free ta_bdcdata.
endmethod. "do_it


method mappe_make.
make_mappe = true.
call method me->mappe_open
exporting
e_name = e_name
e_keep = e_keep
importing
i_error = i_error.
endmethod. "makemap


method mappe_openstatus.
i_open = mappe_is_open.
endmethod. "mappe_openstatus


method mappe_aktivstatus.
data lines type i.
wait up to 1 seconds.
select count( * ) from apqi into lines
where destsys = space
and destapp = space
and datatyp = 'BDC '
and mandant = sy-mandt
and groupid = e_name
and formid = space
and qattrib = space
and qstate <> 'E'
and qstate <> 'F'
and credate = my_datum.
if lines > 0.
i_aktiv = true.
else.
i_aktiv = false.
endif.
endmethod. "mappe_aktivstatus


method mappe_close.
i_error = 1.
check mappe_is_open = true.
call function 'BDC_CLOSE_GROUP'
exceptions
not_open = 1
queue_error = 2
others = 3.
i_error = sy-subrc.
if i_error = 0.
mappe_is_open = false.
endif.
commit work and wait.
endmethod. "mappe_close


method mappe_play.

* SELECT SINGLE qid
* INTO bi_qid
* FROM apqi
* WHERE destsys = space
* AND destapp = space
* AND datatyp = 'BDC '
* AND mandant = sy-mandt
* AND groupid = e_name
* AND formid = space
* AND qattrib = space
* AND qstate = space "Status
* AND credate = my_datum.
* IF NOT bi_qid IS INITIAL.
* CALL METHOD me->mappe_close.
* CHECK mappe_is_open = false.
* SUBMIT rsbdcbtc_sub WITH qid = bi_qid.
* SUBMIT rsbdcbtc_sub WITH queue_id = bi_qid "ow20121127
* AND RETURN.
* ENDIF.

submit rsbdcsub with mappe = e_name "#EC *
with von = my_datum
with bis = my_datum
with b_d_c = 'BDC '
with fehler = ' '
with z_verarb = 'X'
with logall = ' ' " Erweitertes Protokoll
and return.

endmethod. "mappe_play


method mappe_open.
check mappe_is_open = false.
call function 'BDC_OPEN_GROUP'
exporting
client = sy-mandt
* DEST = FILLER8
group = e_name
* HOLDDATE = FILLER8
keep = e_keep
user = bi_user
importing
qid = bi_qid
exceptions
client_invalid = 1
destination_invalid = 2
group_invalid = 3
group_is_locked = 4
holddate_invalid = 5
internal_error = 6
queue_error = 7
running = 8
system_lock_error = 9
user_invalid = 10
others = 11.
i_error = sy-subrc.
if i_error = 0.
mappe_is_open = true.
endif.
endmethod. "mappe_open

endclass. "zcl_new_batchinput IMPLEMENTATION
*

Seite 1 von 1

Vergleichbare Themen

2
Antw.
1667
Views
Batch input
von BMWi801 » 24.03.2018 11:16 • Verfasst in ABAP® für Anfänger
0
Antw.
1541
Views
Batch Input
von SwordMaster » 03.12.2007 07:39 • Verfasst in ABAP® Core
1
Antw.
483
Views
Batch-Input
von dkast » 15.12.2020 14:43 • Verfasst in ABAP® für Anfänger
6
Antw.
21244
Views
Batch Input
von Mamba » 30.05.2005 09:40 • Verfasst in ABAP® für Anfänger
0
Antw.
1459
Views
Batch-Input mit XML Schema
von Daven » 31.05.2013 09:45 • Verfasst in SAP - Allgemeines

Aktuelle Forenbeiträge

PDF-Anzeige unter EDGE
vor 4 Tagen von jocoder 2 / 66
Etikettendruck mit SmartForms
vor einer Woche von a-dead-trousers 2 / 67

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Aktuelle Forenbeiträge

PDF-Anzeige unter EDGE
vor 4 Tagen von jocoder 2 / 66
Etikettendruck mit SmartForms
vor einer Woche von a-dead-trousers 2 / 67

Unbeantwortete Forenbeiträge

Zwischensumme Adobe Forms
vor 3 Wochen von Lucyalison 1 / 129
Group Items auf einer Filterbar
vor 4 Wochen von Bright4.5 1 / 164