' DuplicateArticles (ArticleNumber : String, MacroFlag : Int, ChargeFlag : Int) ' ---------------------------------------------------------------------------- ' Funktionen zur Behandlung mehrfach vorkommender ' Artikelnummern. Daten werden im Array DUPL_ARTICLE_LIST ' gespeichert und verwaltet. ' ' Returns: - ' ---------------------------------------------------------------------------- ' Copyright (c) 2021 by Digital Data GmbH ' ' Digital Data GmbH • Ludwig-Rinn-Strasse 16 • D-35452 Heuchelheim ' Tel.: 0641/202360 • E-Mail: info-flow(at)digitaldata.works ' ---------------------------------------------------------------------------- ' Creation Date / Author: 15.04.2021 / MP ' Version Date / Editor: 15.04.2021 / MP ' Version Number: 4.0.0.0 Const ARTICLE_IS_NOT_IN_DUPLICATES_LIST = -199 Const GRIDLINE_INDEX_IS_NOT_CHOOSEABLE = -198 Const NO_GRIDLINE_INDEX_CHOSEN = -197 CONST USE_ORIGINAL_ROW = -196 ' Legt für jeden scannbaren Artikel einen Satz in der Duplikate-Struktur an ' und zählt wie oft dieser Artikel vorkommt. ' Für Artikel innerhalb eines Macros wird zusätzlich ein eigener Zähler hochgesetzt. Sub AddArticleNumberToDuplList(ArticleNumber, MacroFlag, ChargeFlag) DuplArrayIndex = ExistArticleInDuplList(ArticleNumber) If DuplArrayIndex = ARTICLE_IS_NOT_IN_DUPLICATES_LIST Then ' Lege neue Zeile an AddTwoDimArrayRow DUPL_ARTICLE_LIST DuplArrayIndex = UBound(DUPL_ARTICLE_LIST, 2) DUPL_ARTICLE_LIST(COLUMN_DUPL_ARTICLE_NUMBER, DuplArrayIndex) = ArticleNumber DUPL_ARTICLE_LIST(COLUMN_DUPL_CHARGE_FLAG, DuplArrayIndex) = ChargeFlag DUPL_ARTICLE_LIST(COLUMN_DUPL_ROW_COUNT, DuplArrayIndex) = 1 DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_ROW_COUNT, DuplArrayIndex) = 0 If (MacroFlag = 2) Then DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_ROW_COUNT, DuplArrayIndex) = 1 End If DUPL_ARTICLE_LIST(COLUMN_DUPL_GRID_LINE_INDEXE, DuplArrayIndex) = "" Else ' Erhöhe Wert in bestehender Zeile currentValue = DUPL_ARTICLE_LIST(COLUMN_DUPL_ROW_COUNT, DuplArrayIndex) DUPL_ARTICLE_LIST(COLUMN_DUPL_ROW_COUNT, DuplArrayIndex) = currentValue + 1 If (MacroFlag = 2) Then currentMacroValue = DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_ROW_COUNT, DuplArrayIndex) DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_ROW_COUNT, DuplArrayIndex) = currentMacroValue + 1 End If End If End Sub ' Reduziert die Zähler für den Artikel, wenn eine Zeile vollständig gescannt wurde. ' Für Macro-Unterteile wird zusätzlich der MacroCounter reduziert Sub ReduceCounterInDuplList(ArticleNumber, MacroFlag) DuplArrayIndex = ExistArticleInDuplList(ArticleNumber) If DuplArrayIndex >= 0 Then ' Vermindert Wert für den Artikel currentValue = DUPL_ARTICLE_LIST(COLUMN_DUPL_ROW_COUNT, DuplArrayIndex) DUPL_ARTICLE_LIST(COLUMN_DUPL_ROW_COUNT, DuplArrayIndex) = currentValue - 1 If (MacroFlag = 2) Then currentMacroValue = DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_ROW_COUNT, DuplArrayIndex) DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_ROW_COUNT, DuplArrayIndex) = currentMacroValue - 1 End If End If End Sub ' Reduziert die Zähler im Sub-Macro-Artikel-Token, wenn eine Zeile vollständig gescannt wurde. ' benötigt die ZeilenNummer des Macro Artikels Sub ReduceSubMacroCounterInDuplList(ArticleNumber, MacroLineNumber) DuplArrayIndex = ExistArticleInDuplList(ArticleNumber) If DuplArrayIndex >= 0 Then TestToken = "#" & MacroLineNumber & "," CurrentMacroLineNumbers = DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_LINE_NUMBERS, DuplArrayIndex) If Len(CurrentMacroLineNumbers) > 0 And InStr(CurrentMacroLineNumbers, TestToken) > 0 Then 'Counter reduzieren! TempMacroLineNumbers = "" SplittedTokens = Split(CurrentMacroLineNumbers) For Each Token In SplittedTokens If (InStr(Token, TestToken) > 0) Then 'Treffer, Counter auslesen, erhöhen und zurückschreiben TempToken = Split(Token, ",") TokenLen = Len(TempToken(1))-1 NewCount = CInt(Left(TempToken(1), TokenLen)) - 1 If NewCount > 0 Then TempMacroLineNumbers = TempMacroLineNumbers & " " & TestToken & NewCount & "#" End If Else ' Kein Treffer, Token wieder zurückschreiben TempMacroLineNumbers = TempMacroLineNumbers & " " & Token End If Next CurrentMacroLineNumbers = TempMacroLineNumbers End If DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_LINE_NUMBERS, DuplArrayIndex) = CurrentMacroLineNumbers End If End Sub ' Ergänzt die GridLine-Indexe für Artikel, die mehrfach vorkommen ' Bedingung: Der Artikel muss bereits in der Duplicate-Struktur ' enthalten sein, und einen Counter > 1 haben. Sub AddGridLineIndexToDuplicateArticles(ArticleNumber, GridLineIndex) DuplArrayIndex = ExistArticleInDuplList(ArticleNumber) If DuplArrayIndex >= 0 Then DuplCount = DUPL_ARTICLE_LIST(COLUMN_DUPL_ROW_COUNT, DuplArrayIndex) If DuplCount > 1 Then CurrentGridLineIndexe = DUPL_ARTICLE_LIST(COLUMN_DUPL_GRID_LINE_INDEXE, DuplArrayIndex) If Len(CurrentGridLineIndexe) > 0 Then CurrentGridLineIndexe = CurrentGridLineIndexe & " " & FormatNumber(GridLineIndex, 0) Else CurrentGridLineIndexe = FormatNumber(GridLineIndex, 0) End If DUPL_ARTICLE_LIST(COLUMN_DUPL_GRID_LINE_INDEXE, DuplArrayIndex) = CurrentGridLineIndexe End If End If End Sub ' Ergänzt die LineNumber der Macro-Hauptartikel für Macro-Sub-Artikel ' Gesammelt werden Tokens in der Form #LN,1#, wenn sie noch nicht vorkommen. ' Der Counter wird hochgezählt, um das Vorkommen des Artikels in verschiedenen Macros abzufangen ' Bedingung: Der Artikel muss bereits in der Duplicate-Struktur ' enthalten sein, und einen Counter > 1 haben. Sub AddMacroLineNumberTokensToDuplicateArticles(ArticleNumber, MacroLineNumber) DuplArrayIndex = ExistArticleInDuplList(ArticleNumber) If DuplArrayIndex >= 0 Then DuplCount = DUPL_ARTICLE_LIST(COLUMN_DUPL_ROW_COUNT, DuplArrayIndex) If DuplCount > 1 Then TestToken = "#" & MacroLineNumber & "," CurrentMacroLineNumbers = DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_LINE_NUMBERS, DuplArrayIndex) If Len(CurrentMacroLineNumbers) <= 0 Then CurrentMacroLineNumbers = TestToken & "1#" ElseIf InStr(CurrentMacroLineNumbers, TestToken) = 0 Then CurrentMacroLineNumbers = CurrentMacroLineNumbers & " " & TestToken & "1#" Else 'Counter erhöhen! TempMacroLineNumbers = "" SplittedTokens = Split(CurrentMacroLineNumbers) For Each Token In SplittedTokens If (InStr(Token, TestToken) > 0) Then 'Treffer, Counter auslesen, erhöhen und zurückschreiben TempToken = Split(Token, ",") TokenLen = Len(TempToken(1))-1 NewCount = CInt(Left(TempToken(1), TokenLen)) + 1 TempMacroLineNumbers = TempMacroLineNumbers & " " & TestToken & NewCount & "#" Else ' Kein Treffer, Token wieder zurückschreiben TempMacroLineNumbers = TempMacroLineNumbers & " " & Token End If Next CurrentMacroLineNumbers = TempMacroLineNumbers End If DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_LINE_NUMBERS, DuplArrayIndex) = CurrentMacroLineNumbers End If End If End Sub ' Prüfe, ob eine Artikelnummer bereits in dem Array enthalten ist ' oder nicht ' Rueckgabewert: Index des Artikels im Array, wenn bereits vorhande, sonst -1 falls nicht vorhanden Function ExistArticleInDuplList(ArticleNumber) ExistArticleInDuplList = ARTICLE_IS_NOT_IN_DUPLICATES_LIST If (UBound(DUPL_ARTICLE_LIST, 2) > -1) Then For DuplArrayIndex = 0 To UBound(DUPL_ARTICLE_LIST, 2) If (DUPL_ARTICLE_LIST(COLUMN_DUPL_ARTICLE_NUMBER, DuplArrayIndex) = ArticleNumber) Then ExistArticleInDuplList = DuplArrayIndex Exit For End If Next End If End Function ' Zählt die MacroLineNumber-Tokens für den Artikel, und gibt ' die Anzahl zurück Function GetMacroLineNumberCount(DuplArrayIndex) Count = 0 SplittetTokens = Split(Trim(DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_LINE_NUMBERS, DuplArrayIndex))) For Each Element In SplittetTokens Count = Count + 1 Next GetMacroLineNumberCount = Count End Function ' Die Funktion gibt die Anzahl der Vorkommen des Artikels zurück. ' Für Macro-Sub-Artikel wird noch der Macro-Counter ausgewertet Function GetCountInDuplList(ArticleNumber) GetCountInDuplList = 0 For DuplArrayIndex = 0 To UBound(DUPL_ARTICLE_LIST, 2) If (DUPL_ARTICLE_LIST(COLUMN_DUPL_ARTICLE_NUMBER, DuplArrayIndex) = ArticleNumber) Then ' COLUMN_DUPL_ROW_COUNT enthält die Gesamtzahl der Vorkommen DuplCounter = DUPL_ARTICLE_LIST(COLUMN_DUPL_ROW_COUNT, DuplArrayIndex) If (DuplCounter > 1) Then ' Wenn mehr als 1 Zeile übrig ist und es ein SN-Artikel ist, müssen wir genauer prüfen, ' ob wir die Auswahlbox anzeigen sollen. ChargeFlag = DUPL_ARTICLE_LIST(COLUMN_DUPL_CHARGE_FLAG, DuplArrayIndex) If (ChargeFlag = 2) Then ' Gibt es noch SN-Artikel in Makros? und in wievielen unterschiedlichen Macros? macroRowCounter = cint(DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_ROW_COUNT, DuplArrayIndex)) ' Anzahl Artikel innerhalb von Macros macroLineCounter = cint(GetMacroLineNumberCount(DuplArrayIndex)) ' Anzahl unterschiedlicher Macros ' Die Abfragebox muss kommen, wenn ' a) SN-Artikel in mehreren unterschiedlichen Macros vorkommen ' b) SN-Artikel innerhalb und ausserhalb von Macros vorkommen ' --> Wir geben die komplette Menge DuplCounter zurück! ' Die Box darf nicht kommen, wenn ' c) wenn SN-Artikel nur ausserhalb von Macros vorkommen ' d) SN-Artikel nur noch in einem Bereich auftauchen, ' --> Wir geben 1 als DuplCounter zurück! If (macroLineCounter = 0 OR _ (macroLineCounter = 1 AND DuplCounter = macroRowCounter)) Then DuplCounter = 1 End If End If End If GetCountInDuplList = DuplCounter Exit For End If Next End Function ' Funktion, die die gewählte Auswahl der InputBox auswertet ' Rückgabewert: gewählte Zeilennummer oder Fehler Function ChooseGridLineIndexFromDuplicates(ArticleNumber) NoValidIndexSelected = True ChooseGridLineIndexFromDuplicates = -1 Do RetValue = ShowDuplicateInputBox(ArticleNumber) If RetValue = ARTICLE_IS_NOT_IN_DUPLICATES_LIST Then ' Der Artikel kommt nicht im Array vor. Abbruch. NoValidIndexSelected = False ChooseGridLineIndexFromDuplicates = -1 ElseIf RetValue = USE_ORIGINAL_ROW Then ' Verwende einfach die schon gefundene Zeile NoValidIndexSelected = False ChooseGridLineIndexFromDuplicates = USE_ORIGINAL_ROW ElseIf RetValue = NO_GRIDLINE_INDEX_CHOSEN Then ' Leere Auswahl oder Abbruch - OK Answer = MsgBox("Wollen Sie die Scanergebnisse für Artikel [" & ArticleNumber & "] wirklich verwerfen?", vbYesno + vbQuestion, DEFAULT_TITLE) If Answer = vbYes Then NoValidIndexSelected = False ChooseGridLineIndexFromDuplicates = -1 End If ElseIf RetValue > 0 Then ' Gültiger Wert wurde ausgewählt NoValidIndexSelected = False ChooseGridLineIndexFromDuplicates = RetValue Else ' Falsche Auswahl - Erneut die InputBox anzeigen. MsgBox "Die gewählte Zeile steht nicht zur Auswahl. Bitte wählen Sie erneut.", vbOKOnly + vbExclamation, DEFAULT_TITLE End If Loop While NoValidIndexSelected End Function ' Die Funktion zeigt eine InputBox mit den Informationen über ' doppelte Artikel. ' Rückgabewert: GridLineIndex der Position die bebucht werden soll Function ShowDuplicateInputBox(ArticleNumber) Set mywin = CWLStart.CurrentModule.Windows.Item(WINDOW_ID) Set Grid = mywin.Controls.Item(GRID_ID).Grid Set amountBox = mywin.Controls.Item(AMOUNT_INPUT) ScannedAmount = Cint(amountBox.Contents) DuplArrayIndex = ExistArticleInDuplList(ArticleNumber) If (DuplArrayIndex < 0) Then ShowDuplicateInputBox = ARTICLE_IS_NOT_IN_DUPLICATES_LIST Exit Function End If ChargeFlag = DUPL_ARTICLE_LIST(COLUMN_DUPL_CHARGE_FLAG, DuplArrayIndex) If ChargeFlag = 2 Then ' Anzeige für SN-Artikel macht nur Sinn, wenn Macro-Artikel involviert sind. If DUPL_ARTICLE_LIST(COLUMN_DUPL_MACRO_ROW_COUNT, DuplArrayIndex) <= 0 Then ShowDuplicateInputBox = USE_ORIGINAL_ROW Exit Function End If End If Dim ChooseableTokens : ChooseableTokens = "" 'Enthält die erlaubten Werte für die Auswahl Dim AlreadyUsedAreasTokens : AlreadyUsedAreasTokens = "" ' #0# = Normaler Artikel, sonst MacroLineIndex Dim InputTitle : InputTitle = DEFAULT_TITLE & " - Auswahl einer Zeilennummer" Dim InputDefault : InputDefault = "" ' Hier machen wir bewusst nichts! InputPrompt = "Der Artikel [" & ArticleNumber & "] kommt mehrfach im Auftrag vor: " & vbNewLine & vbNewLine SplittetValues = Split(DUPL_ARTICLE_LIST(COLUMN_DUPL_GRID_LINE_INDEXE, DuplArrayIndex)) For Each GridLineIndex In SplittetValues : Do Total = Cint(Grid.GetCellValue(Cint(GridLineIndex), COLUMN_TOTAL)) Scanned = Cint(Grid.GetCellValue(Cint(GridLineIndex), COLUMN_SCANNED)) Amount = Total - Scanned If (Amount > 0) Then MacroFlag = Cint(Grid.GetCellValue(Cint(GridLineIndex), COLUMN_MACRO_FLAG)) If (ChargeFlag = 0) Then ' Normale Artikel ChooseableTokens = ChooseableTokens & " #" & GridLineIndex & "# " InputPrompt = InputPrompt & "Zeile " & GridLineIndex & vbTab & " - Menge " & Amount If MacroFlag = 2 Then InputPrompt = InputPrompt & " (Package)" End If InputPrompt = InputPrompt & vbNewLine Else ' SN-Artikel / Späte Ausprägungen ' Hier muss entschieden werden, ob ein Satz überhaupt angezeigt werden soll MacroLineNumberToken = "#" & Grid.GetCellValue(Cint(GridLineIndex), COLUMN_MACRO_LINE_NUMBER) & "#" If (InStr(AlreadyUsedAreasTokens, MacroLineNumberToken) = 0) Then AlreadyUsedAreasTokens = AlreadyUsedAreasTokens & " " & MacroLineNumberToken ChooseableTokens = ChooseableTokens & " #" & GridLineIndex & "# " InputPrompt = InputPrompt & "Zeile " & GridLineIndex & vbTab & " - Menge " & Amount If MacroFlag = 2 Then InputPrompt = InputPrompt & " (Package)" End If InputPrompt = InputPrompt & vbNewLine Else Exit Do End If End If End If Loop While False: Next InputPrompt = InputPrompt & vbNewLine & "Auf welche Zeile soll die gescannte Menge [" & ScannedAmount & "] gebucht werden?" inputBoxValue = InputBox(InputPrompt, InputTitle, InputDefault) Select Case True Case IsEmpty(inputBoxValue) ' Abbruchbutton der InputBox geklickt ShowDuplicateInputBox = NO_GRIDLINE_INDEX_CHOSEN Case "" = Trim(inputBoxValue) ' Kein Wert eingegeben und OK geklickt ShowDuplicateInputBox = NO_GRIDLINE_INDEX_CHOSEN Case Else ' Wert eingegeben und OK geklickt testToken = "#" & inputBoxValue & "#" If (InStr(ChooseableTokens, testToken) > 0) Then ' Alles Rotscha in Kambodscha! ShowDuplicateInputBox = inputBoxValue Else ' Ungültiger Wert ShowDuplicateInputBox = GRIDLINE_INDEX_IS_NOT_CHOOSEABLE End If End Select End Function