feat: handle duplicates with file source info (v1.0.1.1)

This commit is contained in:
2026-02-27 12:04:49 +01:00
parent a76a6766a5
commit 63cff880a5
5 changed files with 71 additions and 8 deletions

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
<Id>2c37abde-33e4-4624-b95a-a0aed1526f1b</Id>
<Version>1.0.1.0</Version>
<Version>1.0.1.1</Version>
<ProviderName>SAT Elektrotechnik GmbH</ProviderName>
<DefaultLocale>de-DE</DefaultLocale>
<DisplayName DefaultValue="SAT - Kabelliste Generator (PROD)"/>

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
<Id>2c37abde-33e4-4624-b95a-a0aed1526f1b</Id>
<Version>1.0.1.0</Version>
<Version>1.0.1.1</Version>
<ProviderName>SAT Elektrotechnik GmbH</ProviderName>
<DefaultLocale>de-DE</DefaultLocale>
<DisplayName DefaultValue="SAT - Kabelliste Generator"/>
<DisplayName DefaultValue="SAT - Kabelliste Generator (DEV)"/>
<Description DefaultValue="Konsolidiert strukturierte Kabelzugdaten aus mehreren Tabellenblättern in eine Gesamtliste."/>
<IconUrl DefaultValue="https://localhost:3000/assets/icon-32.png"/>
<HighResolutionIconUrl DefaultValue="https://localhost:3000/assets/icon-64.png"/>
@@ -73,8 +73,8 @@
</bt:Urls>
<bt:ShortStrings>
<bt:String id="GetStarted.Title" DefaultValue="Willkommen zum Kabel-Konsolidierungs-Tool!"/>
<bt:String id="CommandsGroup.Label" DefaultValue="SAT-Elektro"/>
<bt:String id="TaskpaneButton.Label" DefaultValue="Kabelliste generieren"/>
<bt:String id="CommandsGroup.Label" DefaultValue="DEV-SAT-Elektro"/>
<bt:String id="TaskpaneButton.Label" DefaultValue="DEV Kabelliste generieren"/>
</bt:ShortStrings>
<bt:LongStrings>
<bt:String id="GetStarted.Description" DefaultValue="Das Tool wurde geladen. Klicke im Menüband Start auf 'Kabelliste generieren', um zu beginnen."/>

View File

@@ -39,6 +39,7 @@ const App: React.FC<AppProps> = () => {
colorNew: "#d4edda", // light green
colorChanged: "#fff3cd", // light yellow/orange
colorDeleted: "#f8d7da", // light red
colorDuplicate: "#ff0000ff", // light orange for duplicates
});
useEffect(() => {

View File

@@ -120,6 +120,7 @@ function buildSheetMappingStatus(sheetInfo: SheetInfo, headerRow: any[], rowInde
availableColumns,
mappings,
isExternal: sheetInfo.isExternal,
fileName: sheetInfo.fileName,
externalData: sheetInfo.externalData
};
}
@@ -187,16 +188,43 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings:
}
}
// Zusatzfelder für die Kabelliste: Länge, gezogen am, von (Monteur)
// Zusatzfelder für die Kabelliste: Länge, gezogen am, von (Monteur), Bemerkung
consolidatedRow.push("");
consolidatedRow.push("");
consolidatedRow.push("");
// Wir speichern temporär die Quelle in der letzten Spalte, um sie später für Duplikate zu nutzen
const sourceInfo = mapping.isExternal ? `${mapping.fileName || 'Externe Datei'} - ${mapping.sheetName}` : mapping.sheetName;
consolidatedRow.push(sourceInfo);
finalData.push(consolidatedRow);
rowsConsolidated++;
}
}
// --- DUPLIKAT PRÜFUNG ---
const cableCountMap = new Map<string, number>();
// Finde heraus, wie oft jede Kabelnummer vorkommt
for (const row of finalData) {
const kNr = String(row[0] || "").trim();
if (kNr) {
cableCountMap.set(kNr, (cableCountMap.get(kNr) || 0) + 1);
}
}
// Schreibe "Duplikat" inkl. Quelle in die Bemerkungs-Spalte, ansonsten leere die Spalte wieder
for (const row of finalData) {
const kNr = String(row[0] || "").trim();
const sourceInfo = row[row.length - 1]; // Temporär gespeicherte Info abrufen
if (kNr && (cableCountMap.get(kNr) || 0) > 1) {
row[row.length - 1] = `Duplikat (aus: ${sourceInfo})`;
} else {
row[row.length - 1] = ""; // Nur Duplikate erhalten einen Eintrag in "Bemerkung"
}
}
// --- ENDE DUPLIKAT PRÜFUNG ---
// Prüfen, ob "Kabelliste" existiert
let targetSheet: Excel.Worksheet;
let listExists = false;
@@ -209,7 +237,7 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings:
listExists = false;
}
const fullHeaders = [...TARGET_COLUMNS.map(tc => tc.id), "Länge", "gezogen am", "von (Monteur)"];
const fullHeaders = [...TARGET_COLUMNS.map(tc => tc.id), "Länge", "gezogen am", "von (Monteur)", "Bemerkung"];
if (listExists) {
try {
@@ -223,6 +251,7 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings:
const formatChangedQueue: { row: number, col: number }[] = [];
const formatDeletedQueue: number[] = [];
const formatDuplicateQueue: number[] = []; // NEU: Queue für Duplikate
const incomingMap = new Map<string, any[]>();
for (const row of finalData) {
@@ -252,6 +281,16 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings:
formatChangedQueue.push({ row: r, col: c });
}
}
// Prüfen ob Bemerkung aktualisiert werden muss (z.B. neues Duplikat)
const bemerkungColIndex = fullHeaders.length - 1;
const inBemerkung = String(inVals[bemerkungColIndex] || "").trim();
existingValues[r][bemerkungColIndex] = inBemerkung;
if (inBemerkung.startsWith("Duplikat")) {
formatDuplicateQueue.push(r);
}
incomingMap.delete(kNr);
} else {
// Entfallen
@@ -295,7 +334,19 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings:
// Neue Zeilen markieren
for (let i = 0; i < newRows.length; i++) {
currentBody.getRow(newRowsStartIndex + i).format.fill.color = settings.colorNew;
const rowIndex = newRowsStartIndex + i;
const rowData = newRows[i];
if (String(rowData[fullHeaders.length - 1]).trim().startsWith("Duplikat")) {
currentBody.getRow(rowIndex).format.fill.color = settings.colorDuplicate;
} else {
currentBody.getRow(rowIndex).format.fill.color = settings.colorNew;
}
}
// Bestehende Duplikat-Zeilen markieren
for (const rowIndex of formatDuplicateQueue) {
currentBody.getRow(rowIndex).format.fill.color = settings.colorDuplicate;
}
table.getRange().format.autofitColumns();
@@ -335,6 +386,15 @@ export async function consolidateData(mappings: SheetMappingStatus[], settings:
// Markiere komplett neu entfernt auf Userwunsch
// Duplikate beim Neu-Erstellen einfärben:
const bodyRange = table.getDataBodyRange();
for (let i = 0; i < finalData.length; i++) {
if (String(finalData[i][fullHeaders.length - 1]).trim().startsWith("Duplikat")) {
bodyRange.getRow(i).format.fill.color = settings.colorDuplicate;
}
}
targetRange.format.autofitColumns();
await context.sync();

View File

@@ -17,6 +17,7 @@ export interface SheetMappingStatus {
mappings: ColumnMappingInfo[];
availableColumns: { name: string; index: number }[];
isExternal?: boolean;
fileName?: string;
externalData?: any[][];
}
@@ -29,6 +30,7 @@ export interface ConsolidateSettings {
colorNew: string;
colorChanged: string;
colorDeleted: string;
colorDuplicate: string;
}
export const TARGET_COLUMNS: TargetColumnDef[] = [