/// <summary> /// Fügt den Zellen Shape der aktuellen Liste hinzu. /// </summary> /// <param name="cellShape"></param> internal void AddCellShape(CellShape cellShape) { if (CellShapes == null) { CellShapes = new List <CellShape>(); } if (cellShape != null) { CellShapes.Add(cellShape); } }
/// <summary> /// Versucht im Worksheet die Shapes mit den Barcodes zu finden. Dabei wird wenigstens ein Zellen /// Cache mit einer leeren Liste an Zellen Shapes erstellt. Wenn der Worksheet null ist, wird null /// zurückgegeben. /// </summary> /// <param name="worksheet"></param> /// <returns></returns> internal static SheetCache CreateSheetCache(Excel.Worksheet worksheet) { //Ist der Sheet vorhanden if (worksheet != null) { //Neuen Zellen Cache erstellen SheetCache cellCache = new SheetCache { CellShapes = new List <CellShape>(), WorksheetName = worksheet.Name }; //Durch alle Shapes im Worksheet laufen foreach (Excel.Shape shape in worksheet.Shapes) { //Prüft den Shape auf Name, null usw. if (CellShape.CheckShapeName(shape)) { //Aktuelle Adresse var addressCurShape = CellShape.GetAddress(shape); //Aktueller Wert var cellValue = worksheet.Range[addressCurShape]?.Value; //Wert und Adresse auf null prüfen if (addressCurShape != null && cellValue != null) { //Adresse, aktueller Wert und Shape im Cache ablegen cellCache.CellShapes.Add(new CellShape { Shape = shape, Address = addressCurShape, Value = cellValue }); } } } //Es wird mindestens ein instanziierter Zellen Cache mit einer leeren instanziierten Liste zurückgegeben. return(cellCache); } //Es gibt nichts return(null); }
/// <summary> /// Fügt diesem WorkbookCache ein CellShape hinzu. Dieser wird als Barcode auf dem Worksheet angezeigt. /// Erzeugt also einen Barcode im <paramref name="workbook"/> und der <paramref name="range"/> /// und passt diesen an die Zelle an <paramref name="fitToCell"/>. /// </summary> /// <param name="workbook">In diesem Workbook soll der Barcode hinzugefügt werden.</param> /// <param name="range">Ein Bereich an Zellen. Die Zellen sollten Inhalte besitzen.</param> /// <param name="xlPlacement">Wie soll der Barcode an die Zelle gebunden sein.</param> /// <param name="fitToCell">Soll der Barcode an die Größe der Zelle angepasst werden.</param> /// <param name="cellFitToPicture">Soll die Zelle an die Größe des Bildes angepasst werden.</param> internal void AddCellShape(Excel.Workbook workbook, Excel.Range range, Excel.XlPlacement xlPlacement = Excel.XlPlacement.xlMove, bool fitToCell = false, bool cellFitToPicture = false) { try { if (workbook?.Name.Equals(WorkbookName) == true && range != null) { //Existiert bereits ein SheetCache zu dem Worksheet if (!HasSheetCache(range.Worksheet)) { //Nein existiert nicht //Neuen SheetCache hinzufügen var shCch = SheetCache.CreateSheetCache(range.Worksheet); if (shCch != null) { AddSheetCache(shCch); } } //Den SheetCache ermitteln var shCache = GetSheetCache(range.Worksheet); if (shCache != null) { //Durch alle Zellen in der range laufen foreach (Excel.Range cell in range) { //Jetzt den CellShape in den SheetCache schreiben, dabei wird er auch auf der Mappe erzeugt shCache.AddCellShape(CellShape.AddShape(cell, xlPlacement, fitToCell, cellFitToPicture)); } } } } catch (Exception) { throw; } }
/// <summary> /// Prüft <paramref name="range"/> auf Änderungen zu den überwachten <seealso cref="CellShapes"/>. /// Sind Änderungen vorhanden, werden diese direkt umgesetzt. Es werden keine neuen Barcodes gefunden. /// </summary> /// <param name="range"></param> internal void CheckRange(Excel.Range range) { if (!range.Worksheet.Name.Equals(WorksheetName)) { throw new ArgumentException($"Worksheet range check failed: Worksheet.Name '{range.Worksheet.Name}' is not the required name '{WorksheetName}'"); } //Ist im Zellen Cache überhaupt ein Shape vorhanden? if (CellShapes?.Count > 0) { //Durch alle Zellen der Range laufen foreach (Excel.Range cell in range.Cells) { //Ist im Zellen Cache irgend eine Adresse welche der Adresse der Zelle entspricht? if (CellShapes.Any(x => x.Address.Equals(cell.Address))) { //Die geänderte Zelle ermitteln var cllShp = CellShapes.First(x => x.Address.Equals(cell.Address)); //Wurde der Inhalt geändert if (!cllShp?.Value?.Equals(cell.Value)) { /* * Ja hier müssen wir einen neuen Shape erstellen, die Formatierung, Wert und Position * des alten übernehmen und diesen im Cache und im Tabellenblatt ersetzen. * Am Ende wird der alte Shape gelöscht. */ //System.Windows.Forms.MessageBox.Show($"Die Zelle {cell.Address} wurde geändert.\nAktueller Worksheet: {range.Worksheet.Name}\nAlter Wert: {cllShp.Value}\nNeuer Wert: {cell.Value}"); try { //Wenn der alte Shape != null ist if (cllShp.Shape != null) { //Hier picken wir die Formatierungsoptionen des alten Shapes auf //Das kann zu einem Fehler führen, weil z.B. das Bild gelöscht wurde try { cllShp.Shape.PickUp(); } catch (Exception) { //Dann löschen wir dies aus dem Cache und //lassen die nächste Zelle prüfen CellShapes.Remove(cllShp); continue; } //Dann erzeugen wir einen neuen Shape CellShape newShape = CellShape.AddShape(cell, cllShp.Shape.Placement, false, false); //Wenn der nicht null ist //Diese Prüfung bewirkt, dass bei einem Löschen des Zelleninhaltes auch der Barcode gelöscht wird if (newShape?.Shape != null) { //dann übernehmen wir Position und Größe des alten newShape.Shape.Top = cllShp.Shape.Top; newShape.Shape.Left = cllShp.Shape.Left; newShape.Shape.Width = cllShp.Shape.Width; newShape.Shape.Height = cllShp.Shape.Height; //Und wir ersetzen die Formatierungsoptionen durch die Optionen welche oben //gepickt wurden newShape.Shape.Apply(); //Dann fügen wir den neuen Shape unserem Cache hinzu CellShapes.Add(newShape); } //Wir löschen den alten Shape cllShp.Shape.Delete(); } //Der Cache wird trotzdem um den alten Cacheeintrag erleichtert. CellShapes.Remove(cllShp); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show( $"Error on replace a barcode in the worksheet\n\n{ex.Message}" , "Error in OBIforExcel" , System.Windows.Forms.MessageBoxButtons.OK , System.Windows.Forms.MessageBoxIcon.Error); } } } } } }