Hallo,
ich möchte die automatisch erzeugte Belegnummer durch ein vorangestelltes Kürzel erweitern.
In dem Trigger in der Tabelle dbo.SalesDocuments finde ich folgende Zeilen:
– Daten im Beleg aktualisieren
UPDATE [SalesDocuments]
SET
[TransactionNumber] = @TransactionNumber,
[IssueNumber] = @IncrementedCounter
WHERE [ID] = @SalesDocumentID
Wenn ich hier [IssueNumber] einen String zuweise, bekomme ich einen Fehler obwohl das Feld in der DB nvarchar(10) ist… IncrementedCounter ist im Trigger als int definiert.
Die IssueNumber soll etwa so aussehen: MP12345678
Hallo,
die Variable @IncrementedCounter ist als numerischer Typ deklariert worden. Um diesen mit einem Zeichen-Präfix zu verketten, müssen Sie den Counter zunächst in einen Zeichentyp umwandeln. Im ausgelieferten Trigger-Code wird das bereits so gemacht und wenn ich da dann ganz simpel ein ‚MP‘ davor setze, dann klappt das wunderbar:
Bei Rückfragen gerne hier melden.
Hallo Björn,
danke für die schnelle Antwort. Das habe ich auch schoin probiert, funktioniert bei mir aber nicht.
Weiter unten im Script wird ja folgendes zugewiesen:
– Daten im Beleg aktualisieren
UPDATE [SalesDocuments]
SET
[TransactionNumber] = @TransactionNumber,
[IssueNumber] = @IncrementedCounter
WHERE [ID] = @SalesDocumentID
Wenn ich hier [IssueNumber] = 12345 eintrage, funktioniert das. Aber nicht mit einer Zeichenkette.
Wie lautet die konkrete Fehlermeldung und wann kommt die?
Die Zeichenkette muss in einfache Anführungszeichen eingeschlossen sein (nicht in doppelte). (Sorry, falls das glasklar ist, aber oft liegt es ja an solchen Kleinigkeiten. )
Sie haben es zwar geschrieben, aber können Sie einen Shot reinstellen, welcher Datentyp „IssueNumber“ bei Ihnen konkret hat?
Benutzen Sie den von uns ausgelieferten Original Trigger-Code? Wenn ja, basierend auf welcher cRM Version? Ist es die Large4 Solution von cRM10? Sonst hängen Sie Ihren Trigger-Code mal hier rein.
Hallo Björn,
die Anführungszeichen passen, der Datentyp von IssueNumber ist nvarchar(10) so wie im Screenshot. in dem Script steht :
DECLARE @IncrementedCounter AS int
....
[IssueNumber] = @IncrementedCounter
Das Sript ist original von Combit, Large4 Solution.
Hier das Script mit der vorgeschlagenen Änderung:
USE [combit_Large4]
GO
/****** Object: Trigger [dbo].[cmbt_Trigger_TransferSalesDocument] Script Date: 09.04.2021 10:16:28 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- combit Relationship Manager
-- Funktion: Bereitstellen eines Triggers zum Wandeln eines Beleges
-- Name: cmbt_Trigger_TransferSalesDocument
-- Produkt: combit Relationship Manager / Microsoft SQL Server
-- combit macht keine Angaben zu einer bestimmten Eignung der Information in diesem Code
-- Irrtümer und Fehler bleiben ausdrücklich vorbehalten und die Angaben erfolgen ohne Gewähr.
-- Die Angaben stellen nur Einzelfallszenarien dar und enthalten keine Garantie der Beschaffenheit
-- der Produkte.
-- Weitergabe des Codes nicht gestattet!
-- Copyright (c) by combit GmbH. Alle Rechte vorbehalten.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Erstellen des Triggers
ALTER TRIGGER [dbo].[cmbt_Trigger_TransferSalesDocument] ON [dbo].[SalesDocuments]
-- Auslösen nur nach dem Einfügen oder Aktualisieren eines Datensatzes
AFTER INSERT, UPDATE
-- Trigger soll nicht ausgeführt werden, wenn ein Replikations-Agent die vom Trigger betroffene Tabelle ändert
NOT FOR REPLICATION
AS
BEGIN
-- Bewirkt, dass die Meldung bezüglich der Anzahl der von einer Transact-SQL-Anweisung oder gespeicherten Prozedur betroffenen Zeilen nicht mehr als Teil des Resultsets zurückgegeben wird
SET NOCOUNT ON
-- Variablen deklarieren
DECLARE @InsertedCount bigint
DECLARE @DeletedCount bigint
DECLARE @Reason int
DECLARE @SalesDocumentID AS uniqueidentifier
DECLARE @SourceDocumentID AS uniqueidentifier
DECLARE @TransactionNumber AS nvarchar(10)
DECLARE @IssueNumber AS nvarchar(10)
DECLARE @Type AS int
DECLARE @IncrementedCounter AS int
DECLARE @IncrementedTransactionCounter AS int
-- Auslesen der Anzahl der Datensätze in der [inserted] und [deleted] - Tabelle
SELECT @InsertedCount = COUNT([ID]) FROM [inserted]
SELECT @DeletedCount = COUNT([ID]) FROM [deleted]
-- Prüfen, ob ein UPDATE-Statement ausgeführt wurde...
IF @DeletedCount = @InsertedCount
SET @Reason = 1
-- Prüfen, ob ein INSERT-Statement ausgeführt wurde...
IF @DeletedCount = 0 AND @InsertedCount > 0
SET @Reason = 2
-- Deklarieren eines SQL-Servercursors, um durch alle Datensätze zu gehen
DECLARE [RecCursorTransferSalesDocument] CURSOR STATIC FORWARD_ONLY READ_ONLY FOR
SELECT [ID], [SourceDocumentID], [TransactionNumber], [IssueNumber], [Type]
FROM [inserted]
-- Öffnet den SQL-Servercursor
OPEN [RecCursorTransferSalesDocument]
-- Ruft die nächste Zeile aus dem SQL-Servercursor ab
FETCH NEXT FROM [RecCursorTransferSalesDocument] INTO @SalesDocumentID, @SourceDocumentID, @TransactionNumber, @IssueNumber, @Type
WHILE @@FETCH_STATUS = 0
BEGIN
-- Nur, wenn ein neuer Datensatz angelegt wird...
IF @Reason = 2
BEGIN
-- Wenn es noch keine Vorgangsnummer gibt...
IF (@TransactionNumber IS NULL) OR (LEN(@TransactionNumber) = 0)
BEGIN
-- neue Vorgangsnummer über Zähler ermitteln
EXEC cmbt_sp_IncrementCounterOutput @sCounterName = '221393660d174c5a93dd06c8e2053ff4', @nIncrement = 1, @Output = @IncrementedTransactionCounter OUTPUT
-- neue Vorgangsnummer für das Schreiben in die Belege-Ansicht vorbereiten
SET @TransactionNumber = CONVERT(nvarchar(10), @IncrementedTransactionCounter)
END
-- Wenn es noch keine Belegnummer gibt...
IF (@IssueNumber IS NULL) OR (LEN(@IssueNumber) = 0)
BEGIN
-- Bei einem Angebot neue Angebotsnummer über Zähler ermitteln
IF @Type = 1
EXEC cmbt_sp_IncrementCounterOutput @sCounterName = '73474394b06a4ec6a69003252004883f', @nIncrement = 1, @Output = @IncrementedCounter OUTPUT
-- Bei einem Auftrag neue Auftragsnummer über Zähler ermitteln
ELSE IF @Type = 2
EXEC cmbt_sp_IncrementCounterOutput @sCounterName = '277291c9e3b646b9a907546947cdcc98', @nIncrement = 1, @Output = @IncrementedCounter OUTPUT
-- Bei einer Rechnung neue Rechnungsnummer über Zähler ermitteln
ELSE IF @Type = 3
EXEC cmbt_sp_IncrementCounterOutput @sCounterName = '0a1b57342a9a4f73bd691db63f29e9ad', @nIncrement = 1, @Output = @IncrementedCounter OUTPUT
-- Bei einem Lieferschein neue Lieferscheinnummer über Zähler ermitteln
ELSE IF @Type = 4
EXEC cmbt_sp_IncrementCounterOutput @sCounterName = 'c2b8ffcf05144045bec4c43b50a5cc04', @nIncrement = 1, @Output = @IncrementedCounter OUTPUT
-- neue Belegnummer für das Schreiben in die Belege-Ansicht vorbereiten
SET @IssueNumber = N'MP' + CONVERT(nvarchar(1000), @IncrementedCounter)
END
-- Wenn es einen Ursprungs-Beleg gibt...
IF @SourceDocumentID IS NOT NULL
BEGIN
-- Belegposten in den neuen Beleg kopieren
INSERT INTO [SalesDocumentItems]
(
[ID],
[SalesDocumentID],
[ProductID],
[ItemNo],
[Description],
[Specification],
[Quantity],
[StorageUnitID],
[UnitPrice],
[VATType],
[ItemTotal],
[ItemTotalVATOnly],
[ItemTaxRate1],
[ItemTaxRate2],
[ItemTotalWithVAT],
[CreatedOn],
[CreatedBy],
[ModifiedOn],
[ModifiedBy]
)
SELECT
NEWID(),
@SalesDocumentID,
[SalesDocumentItems].[ProductID],
[SalesDocumentItems].[ItemNo],
[SalesDocumentItems].[Description],
[SalesDocumentItems].[Specification],
[SalesDocumentItems].[Quantity],
[SalesDocumentItems].[StorageUnitID],
[SalesDocumentItems].[UnitPrice],
[SalesDocumentItems].[VATType],
[SalesDocumentItems].[ItemTotal],
[SalesDocumentItems].[ItemTotalVATOnly],
[SalesDocumentItems].[ItemTaxRate1],
[SalesDocumentItems].[ItemTaxRate2],
[SalesDocumentItems].[ItemTotalWithVAT],
[SalesDocumentItems].[CreatedOn],
[SalesDocumentItems].[CreatedBy],
[SalesDocumentItems].[ModifiedOn],
[SalesDocumentItems].[ModifiedBy]
FROM [SalesDocumentItems]
WHERE [SalesDocumentID] = @SourceDocumentID
END
-- Daten im Beleg aktualisieren
UPDATE [SalesDocuments]
SET
[TransactionNumber] = @TransactionNumber,
[IssueNumber] = @IncrementedCounter
WHERE [ID] = @SalesDocumentID
END
-- Nur, wenn ein neuer Datensatz angelegt wird oder bestimmte Felder manipuliert werden...
IF (@Reason = 2) OR (@Reason = 1 AND (UPDATE([Total]) OR UPDATE([TotalTaxRate1]) OR UPDATE([TotalTaxRate2]) OR UPDATE([TotalWithTax])))
-- gespeicherte Prozedur ausführen, um die Summen im Beleg neu zu berechnen
EXECUTE [cmbt_sp_RecalcSalesDocument] @SalesDocumentID
-- Ruft die nächste Zeile aus dem SQL-Servercursor ab
FETCH NEXT FROM [RecCursorTransferSalesDocument] INTO @SalesDocumentID, @SourceDocumentID, @TransactionNumber, @IssueNumber, @Type
END
-- Schließt den geöffneten SQL-Servercursor
CLOSE [RecCursorTransferSalesDocument]
-- Entfernt den SQL-Servercursorhinweis
DEALLOCATE [RecCursorTransferSalesDocument]
END
Sorry die Antwort hat sich etwas verzögert. Eine kleine Knobelaufgabe war dann auch noch der Name Ihres Trigger-Codes. Denn den gibt es in der Large4 so nicht. Der Trigger Code scheint irgendwie aus der alten Large3 Solution zu stammen.
Probieren Sie einmal aus, dass Sie
beim Setzen der Belegnummer die @IssueNumber
zuweisen (und nicht den @IncrementCounter
). Sie haben schließlich oben ja die @IssueNumber
mit dem ‚MP‘ Präfix versehen.
Wenn es weiterhin „nicht geht“, dann müssen Sie mal die genaue Fehlermeldung zitieren.
Guten Abend,
wo finde ich denn den Name des Zählers in der Datenbank?
@sCounterName = ‚277291c9e3b646b9a907546947cdcc98‘
Wir würden gerne einen neuen Belegtypen anlegen. Der neue Zähler wurde auch bereits schon angelegt im Programm. Nur den Namen kann ich nirgendwo finden.
Danke!
Viele Grüße
Matthias
Kurz für die stillen Mitlesenden zur Erklärung:
Die Belege nutzen (im Unterschied zu Kontakte-KundenNr oder Firmen-KundenNr in der Large-Solution) direkt per Trigger den Zugriff auf die Zähler Datenbankserver-seitig, damit in jedem Fall auch bei an combit CRM „vorbei“ angelegte Belege garantiert eine fortlaufende Nummer bekommen.
Die „Automatischen Zähler“ …
werden in der Datenbank in der Tabelle
cmbt_autoinc_counters
verwaltet:Da in der Benutzeroberfläche „normalerweise“ die ID nicht bekannt sein muss, zeigen wir die auch nicht an, daher „finden“ Sie auch nicht so einfach die richtige, um jetzt den „low-level-Trigger“-Ansatz vervollständigen zu können (Spoiler: die Info steckt in der .cRM Projektdatei). Mein Tipp: vergeben Sie temporär für Ihren neuen Zähler einen leicht wiedererkennbaren Startwert und suchen kurz die dazu dann korrespondierende Zeile in der cmbt_autoinc_counters
und nehmen den COUNTERNAME
-Wert.
Und wir überlegen uns, ob wir die technische ID aus vorgenannten Gründen als zusätzliche Spalte im Dialog nicht auch deswegen besser einblenden sollten - auch wenn wir früher dachten, dass wir diese technische Info verbergen könnten, weil vermeintlich eh alles interaktiv über das UI läuft.
Perfekt - vielen Dank für die Information!
Grüße
Matthias