in Excel-Datei bestimmte Spalten nach Namen suchen und löschen

  • VB.NET
  • .NET 5–6

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von Kasi.

    in Excel-Datei bestimmte Spalten nach Namen suchen und löschen

    Hallo,

    gleich vorne weg, ich bin kein Programmierer.
    Ich hoffe aber, das ihr mir vielleicht trotzdem weiterhelfen könnt!?

    Ich bekomme mehrere Excel-Listen pro Woche, welche relativ groß sind mit 20-40 Spalten.
    Von diesen Spalten sind aber nur 10 Stück für mich relevant und es ist sehr mühsam die restlichen Spalten immer von Hand zu löschen, da die wichtigen Spalten manchmal am Anfang und manchmal mittendrin sind.
    Die Überschriften der Spalten sind in der Zeile 2 oder 3 und sind aber bei allen Listen gleich bezeichnet.

    Nun hatte ich mir überlegt über ein kleines Programm, welches ich mit Visual-Studio in VB.Net erstelle, die unnötigen Spalten automatisch löschen zu lassen, in dem das Programm nach den Überschriften/Bezeichnungen sucht.

    Nach intensiver Suche bin ich auch schon auf einen gut Ansatz für mich gestoßen, aber leider wird mir die Zeile 25+27 falsch angegeben.
    Zusätzlich hatte die Datei Verknüpfung gefehlt, diese habe ich in Zeile 9-11 angepasst - ich hoffe das ist so richtig!?
    Wenn ich "Option Strict On" rausnehme, habe ich zwar keine Fehler mehr, aber das Programm macht dann trotzdem nicht was es soll und die Excel-Datei wird gesperrt, da sie dann in Verwendung ist und ich Excel dann per Taskmanager schließen muss.
    Könnt ihr mir bitte helfen mit dem Code?

    Hier ist mein aktueller Code :

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.IO
    3. Imports Microsoft.Office.Interop
    4. Public Class Form1
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. Dim Excel As Microsoft.Office.Interop.Excel.Application
    7. Dim xlWB As Microsoft.Office.Interop.Excel.Workbook
    8. Dim Path = "K:\Temp\Test.xlsx"
    9. Excel = New Microsoft.Office.Interop.Excel.Application
    10. xlWB = Excel.Workbooks.Open(Path)
    11. Dim xlWSTabelle1 As Excel.Worksheet = CType(CType(xlWB.Sheets("Tabelle1"), Excel.Worksheet), Excel.Worksheet)
    12. Dim xlWSTabelle2 As Excel.Worksheet = CType(CType(xlWB.Sheets("Tabelle2"), Excel.Worksheet), Excel.Worksheet)
    13. Dim xlSheets As Object
    14. Dim xlSheetsArray(0 To 1) As Excel.Worksheet
    15. Dim k As Long
    16. Dim i As Long
    17. xlSheetsArray(0) = xlWSTabelle1
    18. xlSheetsArray(1) = xlWSTabelle2
    19. For Each xlSheets In xlSheetsArray
    20. With xlSheets
    21. k = .UsedRange.Columns.Count
    22. For i = k To 1 Step -1
    23. Select Case LCase(.UsedRange.Cells(1, i).Value)
    24. 'Diese Spalten nicht löschen
    25. Case "Ziffer", "#Num_IT", "Produkt A", "Kunde 1" '...
    26. Case Else
    27. 'alle anderen Spalten löschen
    28. .UsedRange.Columns(i).Delete()
    29. End Select
    30. Next i
    31. End With
    32. Next xlSheets
    33. End Sub
    Aus Interop.Excel bin ich ziemlich raus, sogesehen ist mein Beitrag leider etwas OT:
    Warum überhaupt etwas programmieren, benutze doch PowerQuery, das ist in Excel enthalten. Es benötigt natürlich auch seine Zeit sich einzuarbeiten. Es hat aber den charmanten Vorteil, dass es auf jeden Arbeitsplatz läuft und sich auch dann noch anpassen läßt, wenn oder falls du nicht mehr da sein solltest.
    Für mich schreit dies auch nach PowerQuery aber wir bekommen dies auch mit .Net hin.

    Du solltest die Datei und Excel auch wieder zumachen, wenn Du fertig bist oder zumindest Excel sichtbar machen.

    Zum Schließen am Ende dies einfügen

    VB.NET-Quellcode

    1. xlWB.Save
    2. xlWB.Close
    3. Set xlWB = nothing
    4. Excel.Quit


    Um Excel sichtbar zu machen füge nach Zeile 10 dies ein:

    VB.NET-Quellcode

    1. Excel.Visible=True


    Für PowerQuery mal so als Ansatz:
    • Alles Pivotieren
    • Die Spalte mit den Überschriften so filtern, dass "Ziffer", "#Num_IT", "Produkt A", "Kunde 1" übrig bleiben
    • Alles Entpivotieren
    • evtl. noch ein bisschen aufräumen
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Willkommen im Forum. :thumbup:

    Neuling schrieb:

    aber leider wird mir die Zeile 25+27 falsch angegeben.
    Es ist von Vorteil, die Fehlermeldungen mit auszugeben.
    Mach aus Object den richtigen Type:

    VB.NET-Quellcode

    1. Dim xlSheets As Excel.Worksheet
    Kleinschrift geht in .NET mit .ToLower().
    Wenn Du Kleinschrift testest, musst Du die Spaltennamen auch klein schreiben:

    VB.NET-Quellcode

    1. Select Case .UsedRange.Cells(1, i).ToString().ToLower()
    2. 'Diese Spalten nicht löschen
    3. Case "ziffer", "#num_it", "produkt a", "kunde 1" '... KLEIN SCHREIBEN
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Vielen Dank, dass ihr mir helft und für die schnelle Antwort.

    Mir wird angezeigt, dass

    VB.NET-Quellcode

    1. .UsedRange.Columns(i).Delete()
    falsch ist -"Option Strict On lässt spätes binden nicht zu. Was ich aber nicht nachvollziehen kann, weil genau das gleiche tue ich doch schon auf die gleiche Weise bei

    VB.NET-Quellcode

    1. .UsedRange.Cells(1, i).ToString()
    und wird nicht als Fehler ausgegeben!?

    Ich habe hinter die einzelnen Zeilen im Code meine Bemerkungen geschrieben, damit ich das Ganze etwas besser verstehe. Ist dies so richtig oder habe ich das falsch verstanden?

    VB.NET-Quellcode

    1. For Each xlSheets In xlSheetsArray
    2. With xlSheets
    3. k = .UsedRange.Columns.Count '<-- es wird festgelegt, dass nicht jede Spalte geprüft wird sondern nur jene, welche Zeichen in den Zellen haben.
    4. For i = k To 1 Step -1 '<-- er geht jede einzelne Spalte durch und prüft diese - 1 steht für eine nach der anderen!?
    5. Select Case .UsedRange.Cells(1, i).ToString() '<-- es werden die Zellen in der Spalte geprüft und mit dem nächsten Schritten (Case) ausgewertet. Wenn das erste "Case" nicht zutrifft, dann "Case Else" und wird somit gelöscht.
    6. 'Diese Spalten nicht löschen
    7. Case "Ziffer", "#Num_IT", "Produkt A", "Kunde 1" '...
    8. Case Else
    9. 'alle anderen Spalten löschen
    10. .UsedRange.Columns(i).Delete()
    11. End Select
    12. Next i
    13. End With
    14. Next xlSheets
    ein anderer weg ist mit OLEDB zu arbeiten, hier ein Bsp.

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Data.OleDb
    3. Public Class Form1
    4. Public Function ExcelOleDb(ByVal strTextPath As String, _
    5. ByVal sSQL As String) As System.Data.DataTable
    6. Dim con As New System.Data.OleDb.OleDbConnection
    7. Dim myCmd As New System.Data.OleDb.OleDbCommand
    8. Dim myadp As New System.Data.OleDb.OleDbDataAdapter
    9. Dim mydt As New System.Data.DataTable
    10. With con
    11. .ConnectionString = "provider=microsoft.ACE.OLEDB.12.0;"
    12. .ConnectionString &= "data source=" & strTextPath & ";"
    13. .ConnectionString &= "Extended Properties = ""Excel 12.0 XML"";"
    14. End With
    15. With myCmd
    16. .Connection = con
    17. .CommandType = CommandType.Text
    18. .CommandText = sSQL
    19. End With
    20. With myadp
    21. .SelectCommand = myCmd
    22. Try
    23. .Fill(mydt)
    24. Catch ex As Exception
    25. MessageBox.Show(ex.Message)
    26. End Try
    27. End With
    28. Return (mydt)
    29. End Function
    30. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    31. 'Sample.1) select all:
    32. DataGridView1.DataSource = ExcelOleDb("E:\TestFolder\excelFilter.xlsx", "SELECT [Ziffer],[#Num_IT],[Produkt A],[Kunde 1] FROM [Tabelle1$]")
    33. End Sub

    Neuling schrieb:

    .UsedRange.Columns(i).Delete()

    Lass das .UsedRange weg. Damit werden die Spalten des Sheet gelöscht und das willst du ja eigentlich.
    UsedRange kann übrigens irreführend sein, wenn die Nutzdaten nicht in Zeile 1 oder Spalte 1 beginnen.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Ein paar Anmerkungen zu deinem Code.

    Die Abfrage nach dem Spaltennamen würde ich z.B. mit Enumerable.Contains Methode machen, damit lässt sich die Gross-/Kleinschreibung ignorieren.

    .UsedRange.Cells(1, i).ToString() ergibt System.Object, du möchtest aber CType(.UsedRange.Cells(1, i), Excel.Range).Value.ToString

    Step -1 Step ist das Inkrement mit dem i pro Schleifendurchlauf erhöht wird, bei negativ Inkrement wird rückwärts gezählt.

    VBA/VB6 Typ Long ist in VB.Net Integer

    Achte darauf das du die Typen richtig deklarierst. z.B. Dim xlSheets As Object -> Dim xlSheets As Excel.Worksheet


    Ich hab dir einmal deinen Code korrigiert/aufgeräumt:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Sub DelColumns()
    2. Dim Path As String = "K:\Temp\Test.xlsx"
    3. 'Diese Spalten nicht löschen
    4. Dim ColumnsToKeep As String() = New String() {"Ziffer", "#Num_IT", "Produkt A", "Kunde 1"} '...
    5. Dim ExcelApp As Excel.Application = CType(Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application")), Excel.Application) ' New Excel.Application
    6. ExcelApp.Visible = True
    7. Dim xlWB As Excel.Workbook = ExcelApp.Workbooks.Open(Path)
    8. Dim xlSheetsArray(0 To 1) As Excel.Worksheet
    9. xlSheetsArray(0) = CType(xlWB.Sheets("Tabelle1"), Excel.Worksheet)
    10. xlSheetsArray(1) = CType(xlWB.Sheets("Tabelle2"), Excel.Worksheet)
    11. For Each xlSheet As Excel.Worksheet In xlSheetsArray
    12. With xlSheet
    13. xlSheet.Activate()
    14. Dim k As Integer = .UsedRange.Columns.Count '<-- es wird festgelegt, dass nicht jede Spalte geprüft wird sondern nur jene, welche Zeichen in den Zellen haben.
    15. For i As Integer = k To 1 Step -1 '<-- er geht jede einzelne Spalte durch und prüft diese - 1 steht für umgekehrte Reihenfolge (von hinten nach vorne)
    16. 'alle Spalten löschen, die nicht in Liste stehen
    17. If Not ColumnsToKeep.Contains(CType(.UsedRange.Cells(1, i), Excel.Range).Value.ToString, StringComparer.CurrentCultureIgnoreCase) Then
    18. CType(.UsedRange.Columns(i), Excel.Range).Delete()
    19. End If
    20. Next i
    21. End With
    22. Next xlSheet
    23. 'Speichern und Schliessen
    24. xlWB.Save()
    25. xlWB.Close()
    26. xlWB = Nothing
    27. ExcelApp.Quit()
    28. End Sub
    Lesen bildet:

    Neuling schrieb:

    VB.NET-Quellcode

    1. Case "Ziffer", "#Num_IT", "Produkt A", "Kunde 1" '...

    RodFromGermany schrieb:

    VB.NET-Quellcode

    1. Case "ziffer", "#num_it", "produkt a", "kunde 1" '... KLEIN SCHREIBEN

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    petaod schrieb:

    Neuling schrieb:

    .UsedRange.Columns(i).Delete()

    Lass das .UsedRange weg. Damit werden die Spalten des Sheet gelöscht und das willst du ja eigentlich.
    UsedRange kann übrigens irreführend sein, wenn die Nutzdaten nicht in Zeile 1 oder Spalte 1 beginnen.


    ich habe es jetzt schon in mehreren Varianten versucht. Auch ohne .UsedRange von .UsedRange.Columns(i).Delete()
    Aber irgendwie will es nicht funktionieren mir wird immer die Zeile als falsch angegeben "Option Strict on lässt spätes binden nicht zu"

    VB.NET-Quellcode

    1. Select Case .UsedRange.Cells(1, i).ToString()
    2. 'Diese Spalten nicht löschen
    3. Case "Ziffer", "#Num_IT", "Produkt A", "Kunde 1" '...
    4. Case Else
    5. 'alle anderen Spalten löschen
    6. .UsedRange.Columns(i).Delete()
    7. End Select


    Bei der verkürzten und übersichtlicheren Version von @HenryV gibt es das Problem, dass VisualStudio mir bei "If Not ColumnsToKeep.Contains(CType(.UsedRange.Cells(1, i), Excel.Range).Value.ToString, StringComparer.CurrentCultureIgnoreCase) Then" eine Ausgelöste Ausnahme als Fehler auswirft. System.NullReferenceException: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."
    Dies verstehe ich nicht, weil die Instanz ist doch mit "i" festgelegt oder etwa nicht?

    Die Version von @Kasi sieht interessant aus. beim ausführen bekomme ich jedoch die Fehlermeldung "Der microsoft.ACE.OLEDB.12.0-Provider ist nicht auf dem lokalen Computer registriert. Dies kann man zwar beheben laut Microsoft, in dem man eine 32-Bit Treiber installiert, was mir aber nicht hilft, da das Programm mal auf 64-Bit Systemen laufen soll ohne Admin-Rechte für irgendwelche Installationen. :(

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

    @Kasi
    funktioniert leider auch nicht. ich habe hinter alle meiner Versuche geschrieben was passiert :

    VB.NET-Quellcode

    1. For Each xlSheets In xlSheetsArray
    2. With xlSheets
    3. k = .UsedRange.Columns.Count
    4. For i = k To 1 Step -1
    5. Select Case .UsedRange.Cells(1, i).ToString()'.ToLower()
    6. 'Diese Spalten nicht löschen
    7. Case "Ziffer", "#Num_IT", "Produkt A", "Kunde 1" '...
    8. Case Else
    9. 'alle anderen Spalten löschen
    10. .Columns(i).Delete() '<-- Option Strict On lässt spätes Binden nicht zu
    11. xlSheets.Columns(i).Delete() '<-- Option Strict On lässt spätes Binden nicht zu
    12. .Range(i).EntireColumn.Delete() '<-- Fehler beim ausführen - System.Runtime.InteropServices.COMException: "Ausnahme von HRESULT: 0x800A03EC
    13. xlSheets.Range(i).EntireColumn.Delete() '<-- Fehler beim ausführen - System.Runtime.InteropServices.COMException: "Ausnahme von HRESULT: 0x800A03EC
    14. .Range(i).Columns.Delete() '<-- Fehler beim ausführen - System.Runtime.InteropServices.COMException: "Ausnahme von HRESULT: 0x800A03EC
    15. xlSheets.Range(i).Columns.Delete() '<-- Fehler beim ausführen - System.Runtime.InteropServices.COMException: "Ausnahme von HRESULT: 0x800A03EC
    16. .Range("A:A").EntireColumn.Delete() '<-- entfernt alle Spalten, ist daher nicht der Sinn und Zweck
    17. xlSheets.Range("A:A").EntireColumn.Delete() '<-- entfernt alle Spalten, ist daher nicht der Sinn und Zweck
    18. End Select
    19. Next i
    20. End With
    21. Next xlSheets
    das hier kann nicht sein

    VB.NET-Quellcode

    1. .Range("A:A").EntireColumn.Delete() '<-- entfernt alle Spalten, ist daher nicht der Sinn und Zweck
    2. xlSheets.Range("A:A").EntireColumn.Delete() '<-- entfernt alle Spalten, ist daher nicht der Sinn und Zweck

    es sollte nur spalte A gelöscht werden

    hier ein Bsp.

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. Try
    3. Dim xlApp As New Microsoft.Office.Interop.Excel.Application()
    4. Dim xlWb As Microsoft.Office.Interop.Excel.Workbook
    5. xlWb = xlApp.Workbooks.Open("E:\a9.xlsx")
    6. Dim WorkSheets As Sheets = xlWb.Sheets
    7. Dim xlSt As Worksheet = CType(WorkSheets("Tabelle2"), Microsoft.Office.Interop.Excel.Worksheet)
    8. xlSt.Range("A:A").EntireColumn.Delete()
    9. xlWb.Save()
    10. xlApp.Quit()
    11. xlApp = Nothing
    12. Catch g As Exception
    13. MessageBox.Show(g.ToString)
    14. End Try
    15. End Sub


    ich würde trotzdem mit OLEDB gehen

    VB.NET-Quellcode

    1. .Range("A:A").EntireColumn.Delete() '<-- entfernt alle Spalten, ist daher nicht der Sinn und Zweck
    2. xlSheets.Range("A:A").EntireColumn.Delete() '<-- entfernt alle Spalten, ist daher nicht der Sinn und Zweck


    läuft in meinem Fall in einer Schleife, weil es ja eigentlich alle Spalten löschen soll, außer die angegebenen.
    Da die Schleife lief und "A:A" angegeben war, hat er dann alles gelöscht.

    Ist es möglich dein Beispiel im Button so zu verändern, dass er alle Spalten löscht, nur bis auf ein paar, welche er nicht löschen soll wie "Ziffer", "#Num_IT", "Produkt A", "Kunde 1" '... ?

    OLEDB ist leider keine Alternative, weil :
    beim ausführen bekomme ich die Fehlermeldung "Der microsoft.ACE.OLEDB.12.0-Provider ist nicht auf dem lokalen Computer registriert. Dies kann man zwar beheben laut Microsoft, in dem man eine 32-Bit Treiber installiert, was mir aber nicht hilft, da das Programm mal auf 64-Bit Systemen laufen soll ohne Admin-Rechte für irgendwelche Installationen.
    Hi,

    hier ein Bsp., Denke daran du must von rechts nach links die Spalten angeben

    VB.NET-Quellcode

    1. Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
    2. Try
    3. Dim xlApp As New Microsoft.Office.Interop.Excel.Application()
    4. Dim xlWb As Microsoft.Office.Interop.Excel.Workbook
    5. xlWb = xlApp.Workbooks.Open("E:\a9.xlsx")
    6. Dim WorkSheets As Sheets = xlWb.Sheets
    7. Dim xlSt As Worksheet = CType(WorkSheets("Tabelle2"), Microsoft.Office.Interop.Excel.Worksheet)
    8. xlSt.Range("O:O").EntireColumn.Delete() ' col15
    9. xlSt.Range("H:L").EntireColumn.Delete() ' col8 bis col12
    10. xlSt.Range("B:C").EntireColumn.Delete() ' col2 und col3
    11. xlWb.Save()
    12. xlApp.Quit()
    13. xlApp = Nothing
    14. Catch g As Exception
    15. MessageBox.Show(g.ToString)
    16. End Try
    17. End Sub


    siehe Bild folgende Spalten bleiben über

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

    Danke @Kasi, das Problem ist jedoch, dass ich nicht die Spalten nach deren Excelnummerierung löschen kann, da ich wie Eingangs geschrieben immer wieder neue ähnliche Exceldateien bekomme, bei welchen nur die Überschriften der Spalten gleich sind, jedoch deren Anordnung nicht immer gleich ist.
    Das bedeutet ich muss erst das Programm nach der Überschrift suchen lassen und die nicht benötigten entfernen.

    Was mir jetzt aber durch testen aufgefallen ist, dass meine Code gar nicht erst die Überschriften der Spalten ausliest, sondern er zählt einfach nur, wie viele es insgesamt sind und löscht diese dann...
    ich hatte einfach mal MessageBox.Show(i.ToString) eingefügt, um es mir anzeigen zu lassen, was er da gerade auswertet. Er zählt dann nur von zum Beispiel 10 auf 1 herunter, also von der Anzahl der Spalten und löscht diese dann.
    Die Frage ist also, wie kann ich die Spaltenüberschriften auslesen/auswerten?

    Hier nochmal der Code :

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim Excel As Microsoft.Office.Interop.Excel.Application
    3. Dim xlWB As Microsoft.Office.Interop.Excel.Workbook
    4. Dim Path = "K:\Temp\Test.xlsx"
    5. Excel = New Microsoft.Office.Interop.Excel.Application
    6. Excel.Visible = True 'false
    7. xlWB = Excel.Workbooks.Open(Path)
    8. Dim xlWSTabelle1 As Excel.Worksheet = CType(xlWB.Sheets("Tabelle1"), Excel.Worksheet)
    9. Dim xlWSTabelle2 As Excel.Worksheet = CType(xlWB.Sheets("Tabelle2"), Excel.Worksheet)
    10. Dim xlSheets As Excel.Worksheet
    11. Dim xlSheetsArray(0 To 1) As Excel.Worksheet
    12. Dim k As Integer
    13. Dim i As Integer
    14. xlSheetsArray(0) = xlWSTabelle1
    15. xlSheetsArray(1) = xlWSTabelle2
    16. For Each xlSheets In xlSheetsArray
    17. With xlSheets
    18. k = .UsedRange.Columns.Count
    19. For i = k To 1 Step -1
    20. Select Case CType(.UsedRange.Cells(1, i), Excel.Range).ToString
    21. 'Diese Spalten nicht löschen
    22. Case "Ziffer", "#Num_IT", "Produkt A", "Kunde 1" '...
    23. Case Else
    24. MessageBox.Show(i.ToString)
    25. 'alle anderen Spalten löschen
    26. CType(.UsedRange.Columns(i), Excel.Range).Delete()
    27. End Select
    28. Next i
    29. End With
    30. Next xlSheets
    31. xlWB.Save()
    32. xlWB.Close()
    33. xlWB = Nothing
    34. Excel.Quit()
    35. End Sub
    versuche es mal so

    VB.NET-Quellcode

    1. Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
    2. Try
    3. Dim xlApp As New Microsoft.Office.Interop.Excel.Application()
    4. Dim xlWb As Microsoft.Office.Interop.Excel.Workbook
    5. xlWb = xlApp.Workbooks.Open("E:\a9.xlsx")
    6. Dim WorkSheets As Sheets = xlWb.Sheets
    7. Dim xlSt As Worksheet = CType(WorkSheets("Tabelle2"), Microsoft.Office.Interop.Excel.Worksheet)
    8. 'xlSt.Range("O:O").EntireColumn.Delete() ' col15
    9. 'xlSt.Range("H:L").EntireColumn.Delete() ' col8 bis col12
    10. 'xlSt.Range("B:C").EntireColumn.Delete() ' col2 und col3
    11. For Each cell In xlSt.Range("A1", "P1")'deine Spalten
    12. If cell.Value <> "Ziffer" Or cell.Value <> "#Num_IT" Or cell.Value <> "Produkt A" Then cell.EntireColumn.Delete()
    13. Next
    14. xlWb.Save()
    15. xlApp.Quit()
    16. xlApp = Nothing
    17. Catch g As Exception
    18. MessageBox.Show(g.ToString)
    19. End Try
    20. End Sub
    Ich hatte wieder den Fehler "Option Strict On lässt spätes binden nicht zu" in Zeile 16.
    Deswegen habe ich Zeile 15 und 16 angepasst zu : Ist dies do richtig?

    VB.NET-Quellcode

    1. For Each cell As Excel.Range In xlSt.Range("A1", "P1") 'deine Spalten
    2. If cell.Value.ToString <> "Ziffer" Or cell.Value.ToString <> "#Num_IT" Or cell.Value.ToString <> "Produkt A" Then cell.EntireColumn.Delete()
    3. Next


    Nun konnte ich zwar den Code ausführen, jedoch bekomme ich dann den Fehler :

    Quellcode

    1. System.NullReferenceException: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."Microsoft.Office.Interop.Excel.Range.Value[object].get hat Nothing zurückgegeben.

    bei

    VB.NET-Quellcode

    1. ​If cell.Value.ToString <> "Ziffer" Or cell.Value.ToString <> "#Num_IT" Or cell.Value.ToString <> "Produkt A" Then cell.EntireColumn.Delete(

    Hi,
    habe mir deinen Code aus Post#1 angesehen, diese Variant funktioniert

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. Try
    3. Dim xlApp As New Microsoft.Office.Interop.Excel.Application()
    4. Dim xlWb As Microsoft.Office.Interop.Excel.Workbook
    5. xlWb = xlApp.Workbooks.Open("E:\a9.xlsx")
    6. Dim WorkSheets As Sheets = xlWb.Sheets
    7. Dim xlSt As Worksheet = CType(WorkSheets("Tabelle2"), Microsoft.Office.Interop.Excel.Worksheet)
    8. For Each cell In xlSt.Range("A1:P1")
    9. Dim currentColumn As Integer
    10. Dim columnHeading As String
    11. For currentColumn = xlSt.UsedRange.Columns.Count To 1 Step -1
    12. columnHeading = xlSt.UsedRange.Cells(1, currentColumn).Value
    13. Select Case columnHeading
    14. 'spalten behalten
    15. Case "Kunde 1", "Ziffer", "#Num_IT", "col2", "Product A", "col14"
    16. Case Else
    17. 'den rest löschen
    18. xlSt.Columns(currentColumn).Delete()
    19. End Select
    20. Next
    21. Next
    22. xlWb.Save()
    23. xlApp.Quit()
    24. xlApp = Nothing
    25. Catch g As Exception
    26. MessageBox.Show(g.ToString)
    27. End Try
    28. End Sub


    eine andere Variante wäre die entsprechenden Spalten in eine neue Tabelle kopieren.
    Diese Variante funktioniert, wenn ich Option Strict On deaktiviere.

    Was man aber soweit ich mich belesen habe nicht machen sollte.
    Die Fehlermeldung "Option Strict On lässt spätes binden nicht zu" erhalte ich in Zeile 12 und 18. Also bei

    VB.NET-Quellcode

    1. ​columnHeading = xlSt.UsedRange.Cells(1, currentColumn).Value

    und

    VB.NET-Quellcode

    1. ​xlSt.Columns(currentColumn).Delete()


    ich habe es schon versucht es umzuändern mit CType( davor, aber das funktioniert dann auch nicht.
    Dieses "Option Strict On"-Problem ist mir irgendwie noch nicht so richtig klar, wie man das beheben soll/kann.


    Der Vorschlag mit dem kopieren der Spalten ist interessant, das wollte ich mir später ansehen, da ich aus einer anderen Tabelle Spalten kopieren muss und diese dann in die eigentliche Excelsheet einfügen muss. dies wollte ich mir aber im Nachhinein erst ansehen, wenn dieser erste Schritt funktioniert.