VBA ohne VBA sinnvoll (Excel)?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von Bartosz.

    VBA ohne VBA sinnvoll (Excel)?

    Hallo,

    man kann mit VB bestimmt auf Excel-Dateien zugreifen und dementsprechend mit Daten füllen.
    Eigentlich hat Excel ja VBA eingebaut, womit man auch schon quasi genau das tun kann.

    Daher die Frage ob es sinnvoll ist VBA zu ignorieren und stattdessen mit vb.net zu arbeiten?

    Falls ja, dann würde ich noch gerne fragen, wie man auf so eine Excel Datei zugreift.

    Viele Grüße
    Ob es sinnvoll ist, VBA zu ignorieren, würde ich nicht behaupten, aber ich nutze ja sowieso VB.net und schreibe auch in eine Excel-Datei, um Daten zu speichern.
    Hier ein Beispielprojekt

    VB.NET-Quellcode

    1. Imports Microsoft.Office.Interop
    2. Imports Microsoft.WindowsAPICodePack.Dialogs
    3. Public NotInheritable Class Form1
    4. Private xlApp As Excel.Application
    5. Private myWorkbook As Excel.Workbook
    6. Private filepath As String = ""
    7. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    8. End Sub
    9. Private Sub Button_auswaehlen_Click(sender As Object, e As EventArgs) Handles Button_auswaehlen.Click
    10. Using SFD1 As New CommonSaveFileDialog
    11. SFD1.Title = "Exceldatei speichern"
    12. SFD1.Filters.Add(New CommonFileDialogFilter("Excel", ".xlsx"))
    13. Dim di As New IO.DirectoryInfo(Application.StartupPath)
    14. If di.Parent.Name = "bin" Then
    15. di = di.Parent.Parent.Parent ' AnyCPU
    16. ElseIf di.Parent.Parent.Name = "bin" Then
    17. di = di.Parent.Parent.Parent.Parent ' x64, x86
    18. End If
    19. If System.IO.Directory.Exists(di.FullName) Then
    20. SFD1.InitialDirectory = di.FullName
    21. Else
    22. SFD1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
    23. End If
    24. If SFD1.ShowDialog() = CommonFileDialogResult.Ok Then
    25. filepath = SFD1.FileName & ".xlsx"
    26. Else
    27. Return ' Bei abgebrochenem Dialog nichts mehr tun!
    28. End If
    29. End Using
    30. End Sub
    31. Private Sub Button_schreiben_Click(sender As Object, e As EventArgs) Handles Button_schreiben.Click
    32. xlApp = New Excel.Application With {
    33. .Visible = True
    34. }
    35. myWorkbook = xlApp.Workbooks.Add()
    36. Dim myWorksheet As Excel.Worksheet = CType(myWorkbook.Sheets("Tabelle1"), Excel.Worksheet)
    37. Dim xlRange As Excel.Range
    38. xlRange = myWorksheet.Range("A2")
    39. xlRange.Value = "so kannst du manuell einen Text in die Datei schreiben"
    40. xlRange = myWorksheet.Range("A3") 'immer wieder den Bereich ändern
    41. ' ausgedachtes Beispiel
    42. Dim Liste_mit_Punkten As New List(Of Point) From {New Point(0, 0), New Point(1, 1), New Point(2, 2)}
    43. For i As Integer = 0 To Liste_mit_Punkten.Count - 1 Step 1
    44. xlRange = CType(myWorksheet.Cells(i + 8, 2), Microsoft.Office.Interop.Excel.Range)
    45. xlRange.Value = Liste_mit_Punkten(i).X
    46. xlRange = CType(myWorksheet.Cells(i + 8, 3), Microsoft.Office.Interop.Excel.Range)
    47. xlRange.Value = Liste_mit_Punkten(i).Y
    48. Next
    49. myWorksheet.SaveAs(filepath, Excel.XlFileFormat.xlWorkbookDefault)
    50. myWorkbook.Close()
    51. xlApp.Quit()
    52. If myWorksheet IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(myWorksheet)
    53. If myWorkbook IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(myWorkbook)
    54. If xlApp IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
    55. xlApp = Nothing
    56. myWorkbook = Nothing
    57. myWorksheet = Nothing
    58. End Sub
    59. Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    60. If myWorkbook IsNot Nothing Then myWorkbook.Close()
    61. If xlApp IsNot Nothing Then xlApp.Quit()
    62. End Sub
    63. End Class



    Wichtig: MS-Office-Produkte immer mit ReleaseComObject freigeben. Sonst kannst du die Datei, wenn du sie auf dem Desktop anklickst, nicht mehr bearbeiten. Du müsstest den PC neustarten.

    PS: Ich sehe gerade, in der For-Schleife steht noch
    myWorksheet.Cells(i + 8, 2), das kannst du natürlich ändern, auf den Bereich, den du haben willst.


    Die Pakete

    VB.NET-Quellcode

    1. Imports Microsoft.Office.Interop
    2. Imports Microsoft.WindowsAPICodePack.Dialogs
    kannst du dir im Visual-Studio-eigenen Nuget-Paket-Manager herunterladen.

    Achte beim Wieder-Einlesen darauf, dass hier das richtige steht. Nicht jedes Sheet heißt "Tabelle1", schon gar nicht heruntergeladene, englische.
    Danke Bartosz, in dem Sinne ignorierst du dann ja VBA, so meinte ich das.

    Ich habe nämlich VBA in einer Excel Tabelle und denke darüber nach das dementsprechend zu verlagern. Der VBA Code ist für die Excel-Datei, er hat keinen externen Mehrwert. Ist aber recht umfangreich und bereitet Daten recht weitgreifend auf.
    Du nutzt VBA mit den Interop Services von Microsoft.
    Wenn man nicht muss, würde ich es nicht benutzen, sondern statt dessen lieber EPPlus (in der Version 4.5.3.3 aus Lizenzgründen).
    Kann man auch über NuGet installieren, Beispiele gibts im Web genug und einfacher als Interop oder OleDB ist es auch.
    Vor allem benötigts du bei EPPlus nicht mal ein installiertes Excel ;)
    Jap und Nö, damit gehts.

    Aber wenn ich kein Workbook öffne, dann macht er auch dieses Fenster auf, schließt es aber automatisch beim Beenden der Anwendung. Ohne .quit

    Ich habe außerdem an meiner ExcelDatei Nach dem Speichern ein weiteres Fenster das aufgeht und mit Ok bestätigt werden muss damit es schließt, kann ich das Fenster auch ansprechen? Ich weiß nichtmal wo das herkommt.

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

    Du musst grundsätzlich unterscheiden zwischen
    • dem Programm allein (siehe mein Bild)
    • einem angefangenen Workbook (wie wenn du auf Neu -> leere Arbeitsmappe klickst)
    • einem Worksheet ( du kannst ja mehrere haben )
    Und wenn du nie ein Workbook angefangen hast, kann sich auch die Anwendung freien Gewissens schließen, denn es muss ja nix gespeichert werden

    Edit: Jetzt habe ich gesehen, dass du editiert hast. Kannst du mal den Code posten?

    Ich komme nochmal auf die Eingangsfrage zurück:

    Haudruferzappeltnoch schrieb:

    man kann mit VB auf Excel-Dateien zugreifen.
    Eigentlich hat Excel ja VBA eingebaut, womit man auch schon quasi genau das tun kann.
    Daher die Frage ob es sinnvoll ist VBA zu ignorieren und stattdessen mit vb.net zu arbeiten?
    Der CrossOver von vb.net nach Excel ist ziemlich tückisch.
    Da bleiben leicht Excel-Programm-Teile unaufgeräumt und unsichtbar im Speicher zurück.
    Und sorgen für Fehler, wenn man mit Excel normal arbeiten will.
    Oder wenn man ein zweites mal in Excel reingrabschen will (wo dann ja die unaufgeräumten Objekte noch rumfahren).
    Oder was Dksksm sagt: Man muss beim Workbook-Grabschen ganz unterschiedlich vorgehen, je nachdem, ob Excel bereits gestartet und in den Arbeitsspeicher geladen ist, oder ob man es von VB.Net aus startet. Und insbesondere das Aufräumen gestaltet sich dann unterschiedlich:
    • Hat deine vb.net-App Excel gestartet, muss sie's auch wieder zumachen.
    • War Excel schon an, darf sie genau das nicht tun, sonst wundert sich der User, warum sein Excel auf einmal zu geht.

    Ach und noch ein Punkt: Excel gibts in 20 Versionen, und wenn du gegen die eine programmierst, funktionierts zunächstmal nicht bei einem User, der ein anderes Excel installiert hat.
    Also alles nicht so einfach.

    Daher würde ich davon abraten, den VBA-Code eines Excel-Workbooks nach VB.Net transferieren zu wollen, wenns da keinen wichtigen Grund für gibt.
    Das VBA ist in Excel gut integriert, stabil und sehr leistungsfähig.
    Ein VB.Net-CrossOver ist prinzipiell eine aufwändige und wackelige Konstruktion.
    Danke @ErfinderDesRades, ich merke es. Wahrscheinlich ist hier doch besser, never touch a running system.

    @Bartosz @Dksksm Der Code ist nur Öffnen Zelle ändern und Schließen bisher als Test.
    Das Fenster hat damit nichts zutun, es kommt aus der Excel-Datei selbst, also auch bei händischem Arbeiten.
    Womöglich hab ich mir die wohl in der Vergangenheit schonmal kaputt gemacht.

    Dksksm schrieb:

    ...nicht benutzen, sondern statt dessen lieber EPPlus. Beispiele gibts im Web genug und einfacher als Interop oder OleDB ist es auch.

    Einfacher als OleDB: ja
    Einfacher als Interop: Falsch. Alle EPPlus Code Beispiele, die ich im Internet gefunden habe, waren zu 100% identisch mit den von mir selbst geschriebenen VB.Net Programmen mit Interop Verweis !!! Lediglich ein paar Codezeilen, um z.B. eine neue Excel Datei zu erzeugen, waren leicht unterschiedlich. Dieser Zusammenhang ergibt sich bereits rein aus der Logik. Wenn ich z.B. in Excel eine Zelle mit einem Wert befüllen möchte, so muss ich die Adresse der Zelle und den Wert angeben. Wie soll das in EPPlus mit weniger Parametern funktionieren ? Kann EPPlus einen der Werte erraten durch Lesen der Gedanken des Benutzers, der vor dem Rechner sitzt ? Wohl eher nicht. Alle Funktionsaufrufe, die ich mit VB.Net + Interop an Excel durchführe, nutzen die minimal notwendigen Parameter. Wie kann EPPlus da einfacher sein ?

    Zur generellen Benutzung von EPPlus kann ich nur sagen: Warum sollte ich eine Third Party Software verwenden, die keinerlei Zusatznutzen gegenüber den Bordmitteln VB.Net + Microsoft Interop hat ? Jede Third Party Software stellt grundsätzlich eine Gefahr für die Sicherheit meiner IT Systeme bzw. für die mir von Kunden anvertrauten IT Systeme dar. Warum sollte ich sowas also mutwillig herbei führen, wenn dazu kein zwingender Grund besteht ?



    ErfinderDesRades schrieb:

    Ach und noch ein Punkt: Excel gibts in 20 Versionen, und wenn du gegen die eine programmierst, funktionierts zunächstmal nicht bei einem User, der ein anderes Excel installiert hat.

    Das ist richtig. Wenn man mehrere verschiedene Excel Versionen bedienen möchte, sollte man für die älteste Version programmieren. Eventuell muss man dann auf das allerneuste Feature von Excel verzichten aber der Code läuft auch auf dem neuesten Excel ohne Probleme. Lediglich wenn extrem veraltete Versionen (Office 2000 oder davor) zum Einsatz kommen, kann es zu Problemen führen.

    ErfinderDesRades schrieb:

    Das VBA ist in Excel gut integriert, stabil und sehr leistungsfähig.

    Das ist richtig. Allerdings ist die IDE von VBA so veraltet (gefühlt Stand 1997), das ich es ablehnen würde, damit zu Arbeiten.

    ErfinderDesRades schrieb:

    Ein VB.Net-CrossOver ist prinzipiell eine aufwändige und wackelige Konstruktion.

    Aufwendig ja, wackelig nein. Du hast mit deinen Betrachtungen in Beitrag Nr. 22 schon auf sehr viele Fallstricke hingewiesen. Das Codebeispiel von Bartosz in Beitrag Nr.2 ist dort in den Zeilen 58 bis 72 hervorragend geschrieben, auch sein Texthinweis "Wichtig". Das ist sehr solide und nicht mehr wackelig. Sollten panische Benutzer eventuell aufgehende Excel Fenster einfach schließen, kann man notfalls noch in Zeile 37 das .visible auf false setzen. Den Benutzer mit einem kleinen Infofenster auf den Betrieb des Programms hinweisen, z.B. Msgbox.show("Bin am Arbeiten, bitte nicht stören"), alle Aktionen in Excel abschließen, die Datei speichern und dann einfach nur das fertige Ergebnis anzeigen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „zorroot“ ()

    Für's normale rumgeraffel mit Zellen, einfärben, Formeln eintragen und son Zeugs ist es sehr nah an dem Code, den du bei Interop auch brauchst.
    Ich bin schon der Meinung, dass aber ganze Tabellen wesentlich komfortablerin Excel geschubst werden als bei Interop.
    Deine Angriffe auf Dinge die niemand gesagt hat, kannst du dir sparen. Wenn du EPPlus nicht leiden kannst verwende es nicht. Von Gedanken lesen war niergends die Rede, das ist persönlich beleidigend was du da schreibst.

    Der Hauptvorteil von EPPlus liegt im übrigen darin, dass du gar kein Excel benötigst um Excel-Workbooks zu schreiben, komplett mit allem drumm und drann.
    Was es nicht kann, zumindest die von mir benutzte version ist: Dateianhänge in Excel einbinden und Drucken.

    Es ist saustabil, da wackelt nichts, was läuft, das läuft dann auch. Sollte man Interop verwenden müssen empfiehlt es sich, nicht direkt auf die installierte Excel-Version zu verweisen, sondern das NuGet-Paket Microsoft.Office.Interop.Excel zu installieren.

    zorroot schrieb:

    EPPlus Code Beispiele, die ich im Internet gefunden habe, waren zu 100% identisch mit den von mir selbst geschriebenen VB.Net Programmen mit Interop Verweis !!!
    Echt?
    Muss man bei EPPlus auch herausfinden, ob Excel schon läuft, und wenn ja, dann besonders reagieren?

    Es kann übrigens auch sein, dass ComInterop inzwischen weniger wackelig ist, als wie ichs vor Jahren kennengelernt habe.
    Da war jede Cell, die man addressiert hat, ein ComObject, und nach Benutzung unbedingt mit Marshal.ReleaseComObject(myCell) wieder freizugeben, wollte man sich nicht erhebliche Probleme einfangen.
    Hat sich das inzwischen gebessert?
    @ErfinderDesRades Es reicht heute, diese drei zu releasen

    VB.NET-Quellcode

    1. If myWorksheet IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(myWorksheet)
    2. If myWorkbook IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(myWorkbook)
    3. If xlApp IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)