I have a list of entries that belong to different components, some of these entries are duplicated between several components, I now want you to show me a table based on this order ("Number\tStatus\tComponents\tDescription") in which you show all entries and their components but for duplicated entries you only show them once but in the column tComponents you show all components in which the entry is duplicated separated with a comma
as Example :
| Number | Status | Components | Description |
| 1 | Active | Component_A, Component_B | Entry 1 Description |
| 2 | Inactive | Component_A | Entry 2 Description |
| 3 | Active | Component_B | Entry 3 Description |
| 4 | Active | Component_A, Component_B | Entry 4 Description |
| 5 | Inactive | Component_C | Entry 5 Description |
I have already written the following two codes but it doesn't work as described above, it generates its own table for each component and what I don't want, I want a table with all entries and their associated components and for duplicate entries write the entries once and in which components are duplicated separated with a comma.
public void ReleaseNotes(string unit, string repository, List paths, string commit, string branch, string anfangTag, string endeTag, string compareBranch, DateTime? startDate, DateTime? endDate, string targetFile)
{
// Connect to Azure DevOps Services
var connection = connectionService.GetTfsConnection();
GitVersionDescriptor sourceVersion = null;
GitVersionDescriptor targetVersion = null;
var release = new Release(unit, repository, paths.Any() ? paths : new List() { string.Empty });
Console.WriteLine($"ReleaseNotes generation to file: '{targetFile}' starting...{Environment.NewLine}");
StringBuilder stringBuilder = new StringBuilder();
// Dictionary zum Speichern von bereits behandelten Komponenten
Dictionary> processedWorkItems = new Dictionary>();
foreach (ReleaseUnit releaseUnit in release.ReleaseUnits)
{
// Prüfen, ob die Komponente bereits behandelt wurde
if (processedWorkItems.ContainsKey(releaseUnit.Name))
{
continue;
}
Console.WriteLine($"Collect data for '{releaseUnit.Name}':");
if (!string.IsNullOrEmpty(commit)) sourceVersion = new GitVersionDescriptor { VersionType = GitVersionType.Commit, Version = commit };
if (!string.IsNullOrEmpty(branch)) sourceVersion = new GitVersionDescriptor { VersionType = GitVersionType.Branch, Version = branch };
if (!string.IsNullOrEmpty(anfangTag)) sourceVersion = new GitVersionDescriptor { VersionType = GitVersionType.Tag, Version = anfangTag };
if (!string.IsNullOrEmpty(compareBranch)) targetVersion = new GitVersionDescriptor { VersionType = GitVersionType.Branch, Version = compareBranch };
if (!string.IsNullOrEmpty(endeTag)) targetVersion = new GitVersionDescriptor { VersionType = GitVersionType.Tag, Version = endeTag };
List features = new List();
List bugs = new List();
Version releaseUnitVersion = null;
foreach (var artifactUnit in releaseUnit.ArtifactUnits)
{
Version version;
var workItems = GetWorkItems(artifactUnit, sourceVersion, targetVersion, startDate, endDate, out version).ToList();
bugs.AddRange(workItems.Where(a => (string)a.Fields["System.WorkItemType"] == "Fehler"));
features.AddRange(workItems.Where(a => (string)a.Fields["System.WorkItemType"] != "Fehler"));
if (releaseUnitVersion == null || releaseUnitVersion < version)
{
releaseUnitVersion = version;
}
}
//Markiere die Komponente als behandelt
if (features.Any())
{
var uniqueFeatureIds = new HashSet(features.Select(f => f.Id.GetValueOrDefault()));
processedWorkItems[releaseUnit.Name] = uniqueFeatureIds;
}
var headerName = $"{releaseUnit.Name}:";
stringBuilder.AppendLine(headerName);
stringBuilder.AppendLine(new string('=', headerName.Length));
if (releaseUnitVersion != null)
{
stringBuilder.AppendLine();
stringBuilder.AppendLine($"V{releaseUnitVersion}");
}
// Remove WorkItems with Tag 'Intern'
bugs = RemoveInternWorkItems(bugs);
features = RemoveInternWorkItems(features);
PrintDetails("1. Fehlerbehebungen", bugs, releaseUnit.Name, stringBuilder);
PrintDetails("2. Neue Funktionen", features, releaseUnit.Name, stringBuilder);
stringBuilder.AppendLine();
stringBuilder.AppendLine($"{Environment.NewLine}{Environment.NewLine}{DescriptionInProgress}");
stringBuilder.AppendLine();
stringBuilder.AppendLine();
}
// Write results to separate file
File.AppendAllText(targetFile, stringBuilder.ToString());
Console.WriteLine("Generation finished.");
Console.WriteLine();
}
private static void PrintDetails(string category, List workItems, string releaseUnitName, StringBuilder stringBuilder)
{
stringBuilder.AppendLine($"{Environment.NewLine}{category}");
if (workItems.Any())
{
stringBuilder.AppendLine("Nummer\tStatus\tKomponenten\tBeschreibung");
stringBuilder.AppendLine("------\t------\t-----------\t------------");
foreach (var workItem in workItems)
{
var id = workItem.Id;
// Überprüfen, ob die ID bereits gedruckt wurde
if (stringBuilder.ToString().Contains($"{id}"))
{
//stringBuilder.AppendLine($"\t\t\t\tDuplikat entfernt (ID: {id})");
continue; // Überspringe Duplikate
}
var state = workItem.Fields["System.State"].ToString();
var title = workItem.Fields["System.Title"];
var componente = releaseUnitName;
var tabsAfterState = "\t";
if (!string.IsNullOrEmpty(state) && state.Length <= 8)
{
tabsAfterState += "\t";
}
stringBuilder.AppendLine($"{id}\t{state}{tabsAfterState}{componente}{tabsAfterState}{title}");
// Zugriff auf Fields vor der Gruppierung
workItem.Fields.TryGetValue("HZD.ReleaseNotes", out var releaseNotesHtml);
if (releaseNotesHtml != null)
{
var releaseNotes = HtmlConverter.ConvertToPlainText(releaseNotesHtml.ToString());
var lines = releaseNotes.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (string.IsNullOrWhiteSpace(line))
continue;
stringBuilder.AppendLine($"\t\t\t{tabsAfterState}\t{Regex.Replace(line, "^ \\* ", "- ")}");
}
stringBuilder.AppendLine();
}
}
}
else
{
stringBuilder.AppendLine(NoWorkItems);
}
}
Prasad RaveendranPosted Mar 9, 2024, 11:01 PM
Here's a modified version of your code incorporating some of the suggested improvements
PrintHeader,PrintWorkItem,PrintReleaseNotes) for better readability and maintainability.TryGetValueto handle potential null values for "System.State" and "System.Title."HashSetto keep track of existing entries and avoid duplicates.aminePosted Mar 6, 2024, 11:45 AM
I have developed a solution that displays the desired results. I'm not sure if it can be programmed in a simpler way.
the Printed Result Shows like that right Now :
1. Fehlerbehebungen
Nummer Status Komponenten Beschreibung
------ ------ ----------- ------------
27155 Fertig e2P_Kern Fehlende prozesssteuerung.dll in der Auslieferung von quartz control (3.8.x und 3.9)
20237 Fertig e2P_Kern SIT Mouseover Text fehlt im Adminclient bei Jobs für die Buttons Anhalten und Fortsetzen
24944 Zugesichert e2P_Kern, e2P_Adapter, e2p_Datenbank, e2P_Kernsystem, e2P_Prozesssteuerung, Deployment, AddressBookService Deaktivieren von Postfächern (Ein-/Ausgangskänale) bewirkt nicht Stop der Nachrichtenverarbeitung eines Mandanten
27683 Fertig e2P_Kern Fehler in Produktion - Nachricht konnte nicht zurückgewiesen werden
27296 Fertig e2P_Kern Bei Mehrfachauslieferung einer Delivery an EGVP-Adapter kann die Zustellung nicht gewährleistet werden (ausgehende EGVP Nachricht oder DE-Mail)
24833 Fertig e2P_Kern Nachricht wird bei EGVP-Return-Code "NO_SUCH_MESSAGE" abgeschlossen statt dauerhaft abgebrochen
2. Neue Funktionen
Nummer Status Komponenten Beschreibung
------ ------ ----------- ------------
28191 Fertig e2P_Kern Erweiterung der Bindungen im Kern um BinaryMessageEncoding
28098 Fertig e2P_Kern Erweiterung der CLI um die Verschlüsselung von Konfigurationsparametern
Mit den neuen Parametern in der CLI können Konfigurationswerte in einer autofac.config mit einem Zertifikat verschlüsselt werden. Dadurch lassen sich sensible Parameter wie die S3Secrets sicher in der Konfigurationsdatei ablegen.
28036 Fertig e2P_Kern Dokumentation der Reihenfolge der Ursprungsdokumente und Originaldokumente
27543 Fertig e2P_Kern Clearing Client: Formatierung der Dateigröße
26059 Fertig e2P_Kern Bereitstellung von Nachrichten in die MsgBox für Altfachverfahren
23869 In Bearbeitung e2P_Kern, e2P_Adapter, e2p_Datenbank, e2P_Kernsystem, e2P_Prozesssteuerung, Deployment, AddressBookService CR 60.7 (EVA-647): FV zu FV Kommunikation
v3.9.0:
- Erster Umsetzungsschritt
- Ermöglichung der FV-zu-FV Kommunikation innerhalb vom Kernsystem
- Die Außengrenzen des Kernsystems unterstützen dies noch nicht
27500 In Bearbeitung e2P_Kern, e2P_Adapter, e2p_Datenbank, e2P_Kernsystem, e2P_Prozesssteuerung, Deployment, AddressBookService CR 114 (EVA-841): Erweiterung MessageBox Error-Handling
27468 In Bearbeitung e2P_Kern, e2P_Adapter, e2p_Datenbank, e2P_Kernsystem, e2P_Prozesssteuerung, Deployment, AddressBookService CR 116 (EVA-896): Adapter Trennung EGVP/
27110 Fertig e2P_Kern CR 85 (EVA-658): Optimierung der Konfiguration
26524 Fertig e2P_Kern CR 120 (EVA-883): Verarbeitung von gewandelten XML-Dateien in e²P und erfolgreiche Einlagerung in e²A
24703 Fertig e2P_Kern SSL Anforderung in deploy.xml schärfen
23408 Fertig e2P_Kern Umstellung der Ports von e2P auf Port der Firewall-Freischaltung
24255 Fertig e2P_Kern Installationsanleitung erstellen
25240 Fertig e2P_Kern Deployment: Umstellen Migration auf SQL generieren und ausführen
aminePosted Mar 6, 2024, 11:35 AM
@Abhishek Yadav @Prasad Raveendran ,
Thank you very much for the time you invested in responding to my concerns. Unfortunately, the current solution removes duplication but prints a separate table for each component. This is not what I want. I want a table with all entries, and duplicated entries should be displayed once. In the "Components" column, I want to see all component names where the entries are duplicated, separated by commas.
with your Solution it Prints like that :
1. Fehlerbehebungen
Nummer Status Komponenten Beschreibung
------ ------ ----------- ------------
27155 Fertig e2P_Kern Fehlende prozesssteuerung.dll in der Auslieferung von quartz control (3.8.x und 3.9)
20237 Fertig e2P_Kern SIT Mouseover Text fehlt im Adminclient bei Jobs für die Buttons Anhalten und Fortsetzen
24944 Zugesichert e2P_Kern Deaktivieren von Postfächern (Ein-/Ausgangskänale) bewirkt nicht Stop der Nachrichtenverarbeitung eines Mandanten
27683 Fertig e2P_Kern Fehler in Produktion - Nachricht konnte nicht zurückgewiesen werden
27296 Fertig e2P_Kern Bei Mehrfachauslieferung einer Delivery an EGVP-Adapter kann die Zustellung nicht gewährleistet werden (ausgehende EGVP Nachricht oder DE-Mail)
24833 Fertig e2P_Kern Nachricht wird bei EGVP-Return-Code "NO_SUCH_MESSAGE" abgeschlossen statt dauerhaft abgebrochen
27683 e2P_Kern, e2P_Kern Duplikat entfernt (ID: 27683)
24944 e2P_Kern, e2P_Kern Duplikat entfernt (ID: 24944)
20237 e2P_Kern Duplikat entfernt (ID: 20237)
2. Neue Funktionen
Nummer Status Komponenten Beschreibung
------ ------ ----------- ------------
28191 Fertig e2P_Kern Erweiterung der Bindungen im Kern um BinaryMessageEncoding
28098 Fertig e2P_Kern Erweiterung der CLI um die Verschlüsselung von Konfigurationsparametern
Mit den neuen Parametern in der CLI können Konfigurationswerte in einer autofac.config mit einem Zertifikat verschlüsselt werden. Dadurch lassen sich sensible Parameter wie die S3Secrets sicher in der Konfigurationsdatei ablegen.
28036 Fertig e2P_Kern Dokumentation der Reihenfolge der Ursprungsdokumente und Originaldokumente
27543 Fertig e2P_Kern Clearing Client: Formatierung der Dateigröße
26059 Fertig e2P_Kern Bereitstellung von Nachrichten in die MsgBox für Altfachverfahren
23869 In Bearbeitung e2P_Kern CR 60.7 (EVA-647): FV zu FV Kommunikation
v3.9.0:
- Erster Umsetzungsschritt
- Ermöglichung der FV-zu-FV Kommunikation innerhalb vom Kernsystem
- Die Außengrenzen des Kernsystems unterstützen dies noch nicht
27500 In Bearbeitung e2P_Kern CR 114 (EVA-841): Erweiterung MessageBox Error-Handling
27468 In Bearbeitung e2P_Kern CR 116 (EVA-896): Adapter Trennung EGVP/Xjustiz
27110 Fertig e2P_Kern CR 85 (EVA-658): Optimierung der Konfiguration
26524 Fertig e2P_Kern CR 120 (EVA-883): Verarbeitung von gewandelten XML-Dateien in e²P und erfolgreiche Einlagerung in e²A
24703 Fertig e2P_Kern SSL Anforderung in deploy.xml schärfen
23408 Fertig e2P_Kern Umstellung der Ports von e2P auf Port der Firewall-Freischaltung
24255 Fertig e2P_Kern Installationsanleitung erstellen
25240 Fertig e2P_Kern Deployment: Umstellen Migration auf SQL generieren und ausführen
27468 e2P_Kern, e2P_Kern, e2P_Kern, e2P_Kern, e2P_Kern Duplikat entfernt (ID: 27468)
27110 e2P_Kern, e2P_Kern, e2P_Kern Duplikat entfernt (ID: 27110)
28098 e2P_Kern, e2P_Kern Duplikat entfernt (ID: 28098)
26059 e2P_Kern, e2P_Kern, e2P_Kern Duplikat entfernt (ID: 26059)
23869 e2P_Kern, e2P_Kern, e2P_Kern Duplikat entfernt (ID: 23869)
28191 e2P_Kern Duplikat entfernt (ID: 28191)
27500 e2P_Kern, e2P_Kern Duplikat entfernt (ID: 27500)
26524 e2P_Kern, e2P_Kern Duplikat entfernt (ID: 26524)
27543 e2P_Kern Duplikat entfernt (ID: 27543)
1. Fehlerbehebungen
Nummer Status Komponenten Beschreibung
------ ------ ----------- ------------
27155 e2P_Adapter Duplikat entfernt (ID: 27155)
20237 e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 20237)
24944 e2P_Adapter, e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 24944)
27683 e2P_Adapter, e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 27683)
27296 e2P_Adapter Duplikat entfernt (ID: 27296)
24833 e2P_Adapter Duplikat entfernt (ID: 24833)
2. Neue Funktionen
Nummer Status Komponenten Beschreibung
------ ------ ----------- ------------
28191 e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 28191)
28098 e2P_Adapter, e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 28098)
28036 e2P_Adapter Duplikat entfernt (ID: 28036)
27543 e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 27543)
26059 e2P_Adapter, e2P_Adapter, e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 26059)
23869 e2P_Adapter, e2P_Adapter, e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 23869)
27500 e2P_Adapter, e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 27500)
27468 e2P_Adapter, e2P_Adapter, e2P_Adapter, e2P_Adapter, e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 27468)
27110 e2P_Adapter, e2P_Adapter, e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 27110)
26524 e2P_Adapter, e2P_Adapter, e2P_Adapter Duplikat entfernt (ID: 26524)
24703 e2P_Adapter Duplikat entfernt (ID: 24703)
23408 e2P_Adapter Duplikat entfernt (ID: 23408)
24255 e2P_Adapter Duplikat entfernt (ID: 24255)
25240 e2P_Adapter Duplikat entfernt (ID: 25240)
1. Fehlerbehebungen
Nummer Status Komponenten Beschreibung
------ ------ ----------- ------------
27155 e2p_Datenbank Duplikat entfernt (ID: 27155)
20237 e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 20237)
24944 e2p_Datenbank, e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 24944)
27683 e2p_Datenbank, e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 27683)
27296 e2p_Datenbank Duplikat entfernt (ID: 27296)
24833 e2p_Datenbank Duplikat entfernt (ID: 24833)
2. Neue Funktionen
Nummer Status Komponenten Beschreibung
------ ------ ----------- ------------
28191 e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 28191)
28098 e2p_Datenbank, e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 28098)
28036 e2p_Datenbank Duplikat entfernt (ID: 28036)
27543 e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 27543)
26059 e2p_Datenbank, e2p_Datenbank, e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 26059)
23869 e2p_Datenbank, e2p_Datenbank, e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 23869)
27500 e2p_Datenbank, e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 27500)
27468 e2p_Datenbank, e2p_Datenbank, e2p_Datenbank, e2p_Datenbank, e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 27468)
27110 e2p_Datenbank, e2p_Datenbank, e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 27110)
26524 e2p_Datenbank, e2p_Datenbank, e2p_Datenbank Duplikat entfernt (ID: 26524)
24703 e2p_Datenbank Duplikat entfernt (ID: 24703)
23408 e2p_Datenbank Duplikat entfernt (ID: 23408)
24255 e2p_Datenbank Duplikat entfernt (ID: 24255)
25240 e2p_Datenbank Duplikat entfernt (ID: 25240)
Abhishek YadavPosted Mar 6, 2024, 5:38 AM
Prasad RaveendranPosted Mar 6, 2024, 2:38 AM
try the below modified code and see
This modification introduces a
duplicateEntriesdictionary to keep track of duplicate entries and their associated components. After processing all work items, it then adds a section to handle duplicate entries and prints them accordingly.