feat: handle duplicates with file source info (v1.0.1.1)
This commit is contained in:
@@ -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(() => {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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[] = [
|
||||
|
||||
Reference in New Issue
Block a user