Mittels C# in Excel schreiben und Excel verwalten

  • C#

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von dani02.

    Mittels C# in Excel schreiben und Excel verwalten

    Hallo Leute,

    ich habe eine Frage über das fernsteuern einer Excel mittels C#.
    Bisher habe ich folgendes Programm geschrieben und habe hierzu ein paar Fragen, wieso was weshalb nicht funktioniert, bzw.
    wie ich es programmiere, dass es funktioniert.

    Quellcode

    1. namespace ConsoleApplication5
    2. {
    3. class Program
    4. {
    5. static void DisplayInExcel()
    6. {
    7. Excel.Application myExcelApplication;
    8. Excel.Workbook myExcelWorkbook;
    9. Excel.Worksheet myExcelWorksheet;
    10. myExcelApplication = null;
    11. try
    12. {
    13. myExcelApplication = new Excel.Application();
    14. myExcelApplication.Visible = true;
    15. myExcelApplication.ScreenUpdating = true;
    16. var myCount = myExcelApplication.Workbooks.Count;
    17. myExcelWorkbook = (Excel.Workbook)(myExcelApplication.Workbooks.Add(System.Reflection.Missing.Value));
    18. myExcelWorksheet = (Excel.Worksheet)myExcelWorkbook.ActiveSheet;
    19. myExcelApplication.ActiveWindow.View = Excel.XlWindowView.xlPageLayoutView;
    20. for (int x = 4; x <=7 ; x++)
    21. {
    22. myExcelWorkbook.Worksheets.Add();
    23. myExcelApplication.ActiveWindow.View = Excel.XlWindowView.xlPageLayoutView;
    24. }
    25. myExcelWorkbook.Worksheets[1].name = "Hilfstabelle";
    26. myExcelWorkbook.Worksheets[2].name = "Deckblatt";
    27. myExcelWorkbook.Worksheets[3].name = "Inhaltsverzeichnis";
    28. myExcelWorkbook.Worksheets[4].name = "Test";
    29. myExcelWorkbook.Worksheets[5].name = "One";
    30. myExcelWorkbook.Worksheets[6].name = "Sonstiges";
    31. myExcelWorkbook.Worksheets[7].name = "Offene Punkte ";
    32.  
    33.  
    34. // ab hier werden die Layouts festgelegt für die Seiten
    35. // beginn deckblatt layout
    36. Excel.Worksheet worksheet = (Excel.Worksheet)myExcelWorkbook.Worksheets["Deckblatt"];
    37. worksheet.Select();
    38.  
    39. myExcelWorksheet.Cells[2, 4] = "Editor";
    40. myExcelWorksheet.Cells[3, 4] = "Phone";
    41. myExcelWorksheet.Cells[4, 4] = "Phone";
    42. myExcelWorksheet.Cells[5, 4] = "Phone";
    43. myExcelWorksheet.Cells[6, 4] = "Phone";
    44.  
    45.  
    46. }
    47. catch
    48. {
    49. }
    50.  
    51. }
    52. public class Test
    53. {
    54. //public int ID { get; set; }
    55. //public double Balance { get; set; }
    56. }
    57.  
    58.  
    59. static void Main(string[] args)
    60. {
    61. DisplayInExcel();
    62. Ordnerverwaltung ordnerverwaltung = new Ordnerverwaltung();
    63. ordnerverwaltung.ShowDialog();
    64. }
    65. }
    66. }


    Die erste Frage:

    Wie bekomme ich am besten hin, dass alle Seiten im Seitenlayout sind, per foreach funktioniert das nicht oder?

    Die zweite Frage:

    Ab Zeile 52 habe ich ja das Sheet "Deckblatt" ausgewählt, wieso schreibt es mir nicht die Worksheet.Cell Werte in dieses Sheet sondern in mein "One" Sheet? Bzw. wie Wechsel ich von den anfangs aktiven in andere Tabellenblätter rein?

    Vielen Dank euch für alle Tipps!
    Als erstes musst du unter Projektexplorer->Verweise->Microsoft.Office.Interop.Excel auswählen->Eigenschaften-Fenster->Interoptypen einbinden auf false stellen. Dann kannst du im Code auch das mit den Interfaces weglassen und gleich viel konkreter programmieren.
    Um etwa auf den Namen eines Worksheets zugreifen zu können musst du dann das Objekte, welches du per myExcelWorkbook.Worksheets[index] erhälst auch noch in ein WorkSheetClass-Objekt casten, auf dem kannst du dann die Name-Property abrufen bzw ändern.

    Ich habs dir jetzt mal zusammengebaut, wie es funzen müsste

    C#-Quellcode

    1. using System;
    2. using System.Windows.Forms;
    3. using Excel = Microsoft.Office.Interop.Excel;
    4. namespace ConsoleApplication5
    5. {
    6. class Program
    7. {
    8. static void DisplayInExcel()
    9. {
    10. Excel.ApplicationClass myExcelApplication;
    11. Excel.WorkbookClass myExcelWorkbook;
    12. Excel.WorksheetClass myExcelWorksheet;
    13. try
    14. {
    15. myExcelApplication = new Excel.ApplicationClass();
    16. myExcelWorkbook = (Excel.WorkbookClass)myExcelApplication.Workbooks.Add();
    17. myExcelWorksheet = (Excel.WorksheetClass)myExcelWorkbook.ActiveSheet;
    18. myExcelApplication.ActiveWindow.View = Excel.XlWindowView.xlPageLayoutView;
    19. for (int x = 4; x <= 7; x++)
    20. {
    21. myExcelWorkbook.Worksheets.Add();
    22. myExcelApplication.ActiveWindow.View = Excel.XlWindowView.xlPageLayoutView;
    23. }
    24. ((Excel.WorksheetClass)myExcelWorkbook.Worksheets[1]).Name = "HilfTabelle";
    25. ((Excel.WorksheetClass)myExcelWorkbook.Worksheets[2]).Name = "Deckblatt";
    26. ((Excel.WorksheetClass)myExcelWorkbook.Worksheets[3]).Name = "Inhaltsverzeichnis";
    27. ((Excel.WorksheetClass)myExcelWorkbook.Worksheets[4]).Name = "Test";
    28. ((Excel.WorksheetClass)myExcelWorkbook.Worksheets[5]).Name = "One";
    29. ((Excel.WorksheetClass)myExcelWorkbook.Worksheets[6]).Name = "Sonstiges";
    30. ((Excel.WorksheetClass)myExcelWorkbook.Worksheets[7]).Name = "Offene Punkte ";
    31. // ab hier werden die Layouts festgelegt für die Seiten
    32. // beginn deckblatt layout
    33. Excel.WorksheetClass worksheet = (Excel.WorksheetClass)myExcelWorkbook.Worksheets["Deckblatt"];
    34. worksheet.Select();
    35. ((Excel.Range)(worksheet.Cells[2, 4])).Value2 = "Editor";
    36. ((Excel.Range)(worksheet.Cells[3, 4])).Value2 = "Editor";
    37. ((Excel.Range)(worksheet.Cells[4, 4])).Value2 = "Editor";
    38. ((Excel.Range)(worksheet.Cells[5, 4])).Value2 = "Editor";
    39. ((Excel.Range)(worksheet.Cells[6, 4])).Value2 = "Editor";
    40. }
    41. catch (Exception ex)
    42. {
    43. MessageBox.Show(ex.Message);
    44. }
    45. }
    46. public class Test
    47. {
    48. //public int ID { get; set; }
    49. //public double Balance { get; set; }
    50. }
    51. static void Main(string[] args)
    52. {
    53. DisplayInExcel();
    54. //Ordnerverwaltung ordnerverwaltung = new Ordnerverwaltung();
    55. //ordnerverwaltung.ShowDialog();
    56. }
    57. }
    58. }


    Was noch fehlt: Du musst mir deinem Exce.Application-Objekt auch noch eine Excel-Datei aufmachen. Unter Excel 2010 ging das noch über Application.Open(...), bei 2015 ist das leider iwie anders, musst mal selber schauen.

    Und zu deiner Frage: Nur weil du das Sheet "Deckblatt" ausgewählt und das Ergebnis einer Variable zugeteilt hast, heißt das nicht, dass sich Änderungen, welche an einem anderen Objekt vorgenommen worden sind, sich auf das ausgwählte Sheet auswirken. Dazu musst du die Änderungen auch auf dem ausgewählten Sheet machen.

    Hoff ich konnte helfen,

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator

    Hallo erstmal und danke für deine Hilfe!

    Das ganze funktioniert glaube ich, nicht ganz so leicht wie du das dir vorstellst, den der ganze Cast Vorgang mit den Excel Ranges etc. ist unzulässig und spuckt eine Fehlermeldung aus in den WindowsForms beim catchen .

    Bei deiner Variante läuft das Programm nur bis zum Moment, das sich die Excel öffnet, ab dann tut sich nichts mehr.

    Ich denke ich muss einfach zuschauen, dass ich meine Sheets wechseln und ansprechen kann damit ich die Werte da reingeschrieben bekomm. Spannend wird es auch wenn ich später Window.Forms Eingaben auch in der Excel ablegen möchte.

    Vielleicht hast du ja dennoch ein Rat wie man das Problem mit den Schnittstellen umgehen kann laut der Fehlermeldung.

    Danke bis dann.


    EDIT: Habe nun herausgefunden wie man ins Sheet wechselt, einfach per Index.
    -> myExcelWorkbook.Worksheets[2].Cells[2, 4] = "Hallo";

    Ansonsten behalte ich meine Version bei.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „dani02“ ()

    dani02 schrieb:

    den der ganze Cast Vorgang mit den Excel Ranges etc. ist unzulässig
    ? Wie genau "unzulässig"? Sieht es bei dir dann auch so aus, wie auf dem Screenshot im Anhang?

    dani02 schrieb:

    spuckt eine Fehlermeldung aus in den WindowsForms beim catchen
    Also zur Laufzeit kommen diverse Fehlermeldungen daher oder hab ich das falsch verstanden?

    dani02 schrieb:

    Vielleicht hast du ja dennoch ein Rat wie man das Problem mit den Schnittstellen umgehen kann
    Auf die Klassen setzen oder nicht direkt über die COM-Schnittstelle sodern Bibliotheken, die das OO-Konzept umsetzen und komplett im "aktuellen" .NET geschrieben sind, setzten. Dazu einfach mal nach C# und Excel bzw OpenSource Libary googlen. SpreadSheetLight soll ne gute Anlaufstelle sein.

    dani02 schrieb:

    laut der Fehlermeldung.
    Welche Fehlermeldungen kommen?
    Etwa Fehler CS1752 Der Interoptyp "WorkbookClass" kann nicht eingebettet werden. Verwenden Sie stattdessen die entsprechende Schnittstelle. ExcelTest1 C:\Users\<user>\Desktop\ExcelTest1\ExcelTest1\Program.cs ?
    Wenn ja, dann, wie ich bereits vorher gepostet habe, die Interop-Typeneinbettung auf false stellen. Dann kannst du mit den Klassen arbeiten.
    Das Problem bei COM-Libs sind die Interfaces, die meistens einfach ein Object oder ein anderes Interface zurück geben. Es gibt aber von vielen Interfaces eine Implementierung als Klasse, die bietet dann zusätzliche Methoden an, die dann einen genaueren Rückgabetypen hat und/oder dir die Möglichkeit biete auf andere (neue) Attribute (WorkSheetClass und die Name Eigenschaft) zuzugreifen.
    Bilder
    • excelinterop_fehler.png

      83,93 kB, 1.306×926, 309 mal angesehen
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Es kommt die Fehlermeldung:

    Das COM-Objekt des typ "System.__ComObject" kann nicht in den Klassentyp
    "Microsoft.Office.Interop.Excel.WorksheetClass" umgewandelt werden.
    COM- Komponenten, die in die CLR eintreten und IProvideClassInfo nicht unterstützen oder die keine registrierte Interop-Assembly aufweisen, werden in den __COM-Object-typ eingebunden. Instanzen dieses Typs können in keine andere Klasse umgewandelt werden. Eine Umwandlung in Schnittstellen ist jedoch möglich, sofern die zugrunde liegende COM-Komponente QueryInterface-Aufrufe für die IID der Schnittelle unterstützt.

    Wenn ich die Interop Typen ausschalte ist das wie auf deinem Screen, jedoch kommt eben jene Fehlermeldung.
    Wenn ich es anhabe funktioniert meine Code immerhin.

    Das ist echt ziemlich blöd mit C# und Excel, leider ..