Blog

News

Easily work with dimensions

Goal
Dimensions in the respective sales, purchasing and financial data sets are to be displayed. Just as it happens with global dimension codes 1 + 2. Currently, the assigned dimensions can only be displayed via Navigate> Dimensions.
Idea
FlowFields are added that represent the dimensions configured in Financial Accounting as dimensions 3-8. FlowFilters are also created, which previously defined FlowFields with the right dimension filter on table 480.
Implementation

Table 348, Funktion CheckIfDimUsed
All entries in table 349 (DimensionValue) must have a valid value in the field „Global Dimenson No.“ according to the selection in table 98 (General Ledger Setup). Therefore, the following code was added at the end of the CheckIfDimUsed function:


IF (BudgetNameChecked=“) AND (AnalysisViewChecked=“) AND (AnalysisAreaChecked=0) THEN BEGIN
DimVal.RESET;
DimVal.SETRANGE(„Global Dimension No.“,DimTypeChecked);
IF DimVal.FINDSET THEN REPEAT
DimVal.“Global Dimension No.“ := 0;
DimVal.MODIFY;
UNTIL DimVal.NEXT=0;
IF DimChecked<>“ THEN BEGIN
DimVal.RESET;
DimVal.SETRANGE(„Dimension Code“,DimChecked);
IF DimVal.FINDSET THEN REPEAT
DimVal.“Global Dimension No.“ := DimTypeChecked;
DimVal.MODIFY;
UNTIL DimVal.NEXT=0;
END;
END;
Example on Table 36 (Sales Header)
Add new FlowFilter Dimension x Filter (x: 3..10) Code20.

Add FlowField Dimension x Code (x: 3..10) Code20.

CalcFormula (x: 3..10):

Lookup(„Dimension Set Entry“.“Dimension Value Code“ WHERE (Dimension Set ID=FIELD(Dimension Set ID),Dimension Code=FIELD(Dimension x Filter)))
CaptionClass (x: 3..10):
‚1,2,x‘
Editable :
No
TableRelation :
„Dimension Value“.Code WHERE (Global Dimension No.=CONST(x))

Create Global Function GetDimensionFilter, called once from each form:

//GenLedgerSetup : Table 98

GenLedgerSetup.GET();
SETFILTER(„Dimension 3 Filter“,GenLedgerSetup.“Shortcut Dimension 3 Code“);
SETFILTER(„Dimension 4 Filter“,GenLedgerSetup.“Shortcut Dimension 4 Code“);
SETFILTER(„Dimension 5 Filter“,GenLedgerSetup.“Shortcut Dimension 5 Code“);
SETFILTER(„Dimension 6 Filter“,GenLedgerSetup.“Shortcut Dimension 6 Code“);

Example on Page 42 (Sales Order, PageType Document)
Add new variable Dimx (x: 3..10) as Code20.

Create new Field

SourceExpr : Dimx (x: 3..10)
TableRelation : (x: 3..10)
„Dimension Value“.Code WHERE (Global Dimension No.=CONST(x))
Caption Class (x: 3..10)
‚1,2,x‘
OnValidate()-Trigger (x: 3..10):
ValidateShortcutDimensionCode(x,Dimx);

Call the new Function GetDimensionFilter inside OnAfterGetCurrentRecord.
Example on Page 9305 (Sales Order List, PageType List)
Create new Field Dimension x Code (x: 3..10).

Call the new Function GetDimensionFilter inside OnAfterGetCurrentRecord.

Watch out : CheckDim3to8

 

Posted by Thomas Marquardt
Howto

T309 „No. Series Line“

In Addition to the Post of Jörg Stryk regarding the bottleneck “No. Series Line” I will present you another solution. Here is his mentioned problem:

Problem:
Technically the Table 309 „No. Series Line“ is pretty small and contains a fixed (more or less) number of records. Whenever a new number is drawn from No. Series, the corresponding record is locked, the last number is read and increased, then the record is updated. When updating the record the lines is locked (ROW X). In some cases this could also mean that the whole data page is also locked (PAG IX), which could lead to blocking issues. Means, for example, if a „No. Series“ is used (e.g. „S-INV+“) the line is locked (ROW X), also the page (PAG IX) blocking another process even when using a different „No. Series“ (e.g. „P-ORD“).

Solution:

If two processes try to lock exactly the same „No. Series Line“ (e.g. „S-INV+“) there’s nothing we could do. In other cases it could be feasible to use dedicated „No. Series Line“-Tables. In my solution I work with temporary „No. Series Line“-Table and RecordRef. We had to change Table 308 and 309, Codeunit 396 and Page 456 and of cause create one or more new „No. Series Line“-Table. Every Time the Codeunit or a user attempts to access or change data this will be redirected to the right „No. Series Line“-Table by using RecordRef and the temporary Table 309.

Performance Table 309

Posted by Thomas Marquardt
News

Echtzeitintegration der Kostenrechnung mit dem Finanzwesen

Verwendung
Bei Verrechnungen im Controlling werden meistens Buchungen erzeugt, die für die Finanzbuchhaltung keine Auswirkungen haben. Diese Buchungen schreiben keine Sachkontenverkehrszahlen fort, sondern es handelt sich um reine Buchungen innerhalb des Controllings. Wenn allerdings eine Verrechnung im Controlling zu einer Änderung des Funktionsbereichs oder eines sonstigen Merkmals führt, das für Auswertungen in der Finanzbuchhaltung relevant ist, kommt es zu einer Verschiebung zwischen den betroffenen Positionen in der Gewinn- und Verlustrechnung. Deshalb muss diese Information an die Finanzbuchhaltung übergeleitet werden. Diese Abstimmung zwischen Controlling und Finanzbuchhaltung erfolgt über die Echtzeitintegration.

Die Echtzeitintegration ermöglicht die sofortige Überleitung aller Controlling-Belege in die Finanzbuchhaltung. Dadurch ist die Finanzbuchhaltung jederzeit mit dem Controlling abgestimmt.

Für jede Buchung im Controlling entsteht ein Beleg im Finanzwesen. Dadurch stehen in den Berichten des neuen Hauptbuchs jederzeit alle Detailinformationen zur Verfügung, die auch in den CO-Belegen enthalten sind, gegliedert nach z. B.:

Funktionsbereich
Kostenstelle
Innenauftrag

Integration
Die von mir umgesetzte Echtzeitintegration ersetzt die oben aufgeführten Abstimmbuchungen. Jede an einer Umbuchung beteiligte Kostenart, welche für die GuV relevant ist, erhält ein zugeordnetes Hauptbuchkonto. Jede Verrechnung im Controlling führ dann über die Echtzeitintegration zu einem zugeordneten Hauptbuchposten.

Posted by Thomas Marquardt
Projektbericht

Integration von Navision und SharePoint

Es ist schon ein paar Jahre her. Zur damaligen Zeit existierte keine zufriedenstellende Lösung am Markt, die genau den Erfordernissen entsprach, Daten aus Navision 4.0 im Web zu präsentieren und Änderungen im Web zurück nach Navision 4.0 zu übertragen. Darüber hinaus sollte der Webauftritt komplett über Navision 4.0 konfiguriert in SharePoint eingebettet sein. Lesen Sie hier weiter um mehr zu erfahren. ()

Posted by Thomas Marquardt
Howto

Generische Anzeige von Änderungsprotokollposten

Häufig muss der Administrator umständlich schauen, wer, wann welche Daten im System erstellt, geändert oder gelöscht hat. Navision stellt hierzu im Standard die konfigurierbare Aufzeichnung von Datenänderungen zur Verfügung. Was aber fehlt, ist die Möglichkeit diese Änderung an der Stelle anzeigen zu lassen, die den Anwender interessiert. Neben den datenschutzrechtlichen Belangen, auf die ich an dieser Stelle nur hinweisen möchte, steht die einfache technische Umsetzung im Vordergrund. Nachfolgend möchte ich die Lösung präsentieren, die es erlaubt, über einen 2-Zeiler diese Ansicht zu konfigurieren.

Diese Funktion muss vor der eigentlichen Verwendung in die Codeunit 423 eingebunden werden oder in einer nach Ihrer Wahl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39PROCEDURE ShowLogEntries(RecRef : RecordRef);
VAR
ChangeLogEntry : Record 405;
KeyRef1 : KeyRef;
KeyFldRef : FieldRef;
i : Integer;
IndexFields : Text[1024];
Text001 : TextConst 'DEU=Keine Änderungsprotokollposten zu %1 (%2) gefunden.;ENU=No Change Log Entries were found on %1 (%2).';
BEGIN
ChangeLogEntry.SETRANGE("Table No.",RecRef.NUMBER);
KeyRef1 := RecRef.KEYINDEX(1);
FOR i := 1 TO KeyRef1.FIELDCOUNT DO BEGIN
KeyFldRef := KeyRef1.FIELDINDEX(i);
CASE i OF
1:
BEGIN
ChangeLogEntry.SETRANGE("Primary Key Field 1 Value",FormatValue(KeyFldRef,RecRef.NUMBER));
IndexFields := STRSUBSTNO('%1 = %2', KeyFldRef.CAPTION, FormatValue(KeyFldRef,RecRef.NUMBER));
END;
2:
BEGIN
ChangeLogEntry.SETRANGE("Primary Key Field 2 Value",FormatValue(KeyFldRef,RecRef.NUMBER));
IndexFields := STRSUBSTNO(IndexFields+', %1 = %2', KeyFldRef.CAPTION, FormatValue(KeyFldRef,RecRef.NUMBER));
END;
3:
BEGIN
ChangeLogEntry.SETRANGE("Primary Key Field 3 Value",FormatValue(KeyFldRef,RecRef.NUMBER));
IndexFields := STRSUBSTNO(IndexFields+', %1 = %2', KeyFldRef.CAPTION, FormatValue(KeyFldRef,RecRef.NUMBER));
END;
END;
END;
IF ChangeLogEntry.FINDFIRST THEN BEGIN
FORM.RUN(FORM::"Change Log Entries",ChangeLogEntry);
END ELSE
MESSAGE(Text001
, RecRef.CAPTION
, IndexFields
);
END;

Nochfolgend kann diese zentrale Funktion wie unten dargestellt verwendet werden:

1
2
3
4
5
6
7
8PROCEDURE ShowChangeLog();
VAR
RecRef : RecordRef;
ChangeLogMgmt : Codeunit 423;
BEGIN
RecRef.GETTABLE(Rec);
ChangeLogMgmt.ShowLogEntries(RecRef);
END;

Posted by Thomas Marquardt
Uncategorized

Der Neustart

Schon so oft habe ich darüber nachgedacht: „Ist es das was Du erreichen wolltest?“ Nicht dass ich bisher richtig unzufrieden war. Vielmehr habe ich gesehen, wie viel möglich ist. „Beschwer dich nicht. Ändere es, wenn es Dir nicht gefällt. Es gibt keinen Anderen, der es für Dich macht.“ Diese und ähnliche Sachen gingen durch meinen Kopf.

Nun habe ich den Mut gefasst und sehe mein Ziel nun klar vor Augen. Warum nicht früher? Ja, warum eigentlich nicht schon früher.

Posted by Thomas Marquardt