schrittweise Ersetzung von VB6-Methoden

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

Es gibt 52 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.


    Len(CType(wks.Cells(3, 1), Excel.Range).Value) -> CType(wks.Cells(3, 1), Excel.Range).Value.lenght
    führt zu:
    Option Strict ON Late Binding error

    habe ich nun so gelöst:

    VB.NET-Quellcode

    1. (CType(wks.Cells(j, 1), Excel.Range).Value).ToString.Length


    Die alternative Laderoutine von ROD (Post #10 in diesem thread) habe ich teilweise integriert, angeapsst und verändert
    Sie löste das Late binding zwar nicht, ich finde Sie aber eleganter und sicherer als meinen Ansatz.
    Vielen Dank dafür.

    Eine Zeile der Laderoutine von ROD habe ich aber nicht übernommen.

    VB.NET-Quellcode

    1. Dim wb As Excel.Workbook = objExcel.Workbooks.OpenDatabase(path)


    führt bei mir zu einem Absturz:
    HRESULT: 0x800A03EC

    Die zu ladende Tabelle ist aber weder eine .xls mit Überlänge noch läuft eine andere Excel Anwedung im Taskmanager.
    Vielleicht ist irgendwo in der Tabelle etwas drin, was nicht korrekt formatiert und somit falsch interpretiert wird.

    Ich habe meine Laderoutinenzeile die ohne Fehler läuft erstmal drin gelassen.
    So sieht das nun aus:

    VB.NET-Quellcode

    1. 'Excel-> einlesen
    2. If System.IO.File.Exists(strFilename) Then
    3. If FileInUse(strFilename) = False Then
    4. Try
    5. 'Variablen für Excel-Ansteuerung
    6. Dim xlApp As New Excel.Application
    7. Dim xlWorkbooks As Excel.Workbooks = xlApp.Workbooks
    8. Dim xlWorkbook As Workbook = xlWorkbooks.Add()
    9. With xlApp
    10. 'Datei öffnen und Daten einlesn
    11. xlWorkbook = .Workbooks.Open(strFilename)
    12. ...

    Mich würde aber interessieren ob jemand zu dem Fehlercode oben noch eine weitere Idee hat ?


    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „Mabbi“ ()

    @Mabbi ToString.Length bringt die Länge eines Strings, im Ernstfall ist der String der Name des Controls, dsas ist nicht das, was Du willst.
    Gib diesen Fehlercode HRESULT: 0x800A03EC direkt bei Frau Google ein, da werden sinnvolle Meldungen aufgelistet.
    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!
    also ich öffne;Lese und schreibe in Excel so

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As System.Object, 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:\TestFolder\vbexcel.xlsx")
    6. Dim xlSt As Microsoft.Office.Interop.Excel.Worksheet = CType(xlWb.Worksheets("Tabelle4"), Worksheet)
    7. Dim ColRange = xlSt.UsedRange.Columns.Count 'used Columns
    8. Dim rowRange = xlSt.UsedRange.Rows.Count 'used rows
    9. 'UsedRanges
    10. 'MessageBox.Show(CStr(ColRange))
    11. 'MessageBox.Show(CStr(rowRange))
    12. With xlSt
    13. 'schreibe in D7
    14. .Range("D17").Value = "56"
    15. 'lese Cell D8
    16. TextBox1.Text = CStr(.Range("D8").Value)
    17. End With
    18. xlWb.Save()
    19. xlApp.Quit()
    20. xlApp = Nothing
    21. Catch g As Exception
    22. MessageBox.Show(g.ToString)
    23. End Try
    24. End Sub


    was machst du denn genau mit Excel ? vielleicht ist das lesen, filtern mit OLEDB besser

    EDIT:
    die Zeile 8 in deinem Code in Post#41

    VB.NET-Quellcode

    1. Dim xlWorkbook As Workbook = xlWorkbooks.Add()

    ist überflüssig, willst ein Tabelle inzufügen ?

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

    @RodFromGermany:
    An der Stelle prüfe ich wie folgt

    VB.NET-Quellcode

    1. 'secu, pruefen ob in Zelle j,1 ein Name steht
    2. If CType(wks.Cells(j, 1), Excel.Range).Value Is Nothing = False Then
    3. If (CType(wks.Cells(j, 1), Excel.Range).Value).ToString.Length > 0 Then


    Um danach den gefundenen Namen in eine List of (String) zu speichern zum Weiterverarbeiten.
    Ich will aber keine "leeren Zellen" übernehmen, sondern nur etwas wo zumindestens iregendetwas drin steht.
    Das prüfe ich über die Länge (und das Vorhandensein) des Inhalts ab.
    Ist für mich schon zielführend ?

    zum HRESULT: 0x800A03EC:
    Ich finde (s.o)
    alte .xls mit zuviel Zeilen/Spalten, habe ich nicht, ist eine .xlsm
    schon laufende Excel Anwendung im taskmanager, habe ich nicht, ich mache vor dem Aufruf eine KillExcel Routine die alle Excel threads ohne mit der Wimper zu zucken erschiesst. (ist glaube ich sogar irgendwo hier aus dem Forum)

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Kill_ExcelInstanz()
    2. 'Alle Excel-Instanzen toeten
    3. Dim Excproclist As Process() = Process.GetProcessesByName("Excel")
    4. For i = 0 To Excproclist.GetUpperBound(0)
    5. If Excproclist(i).MainWindowTitle = "" Then Excproclist(i).Kill()
    6. Next
    7. Excproclist = Nothing
    8. End Sub


    Dann finde ich noch eventuell Konvertierungsfehler der vorliegenden Tabelle.
    Die .xlsm, die ich dort zur Datenaufbereitung lade ist vorsichtig ausgedrückt "wild", jahrelang (Korrektur: Jahrzehnt+)von Hand gepflegte Excel Tabelle mit Makros.
    Das steht viel Müll drin, ich suche mir halt die Sachen raus, die ich brauche und verarbeite das in einer sinnvollen Datatable und speichere es in meiner Datenbank.
    Weiter bin ich bis dato bei der Fehleranalyse noch icht gekommen.

    Da ich aber aktuell an dem neuen Tool bastel, das die o.g. Daten lädt, verarbeitet, visualisert, editierbar macht und in die Datenbank speichert, bin ich vorerst auf meine Laderoutine zurück gegangen.
    Dem Fehler probier ich noch rauszufinden, evtl. lerne ich dann ja etwas über die Unterschiede zwischen meinem alten und Deinem neuen Code.

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

    @Mabbi Von solch internem datenbank-Zeugs habe ich keine Ahnung, da lass ich lieber die Finger von.
    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!

    Kasi schrieb:

    also ich öffne;Lese und schreibe in Excel so
    was machst du denn genau mit Excel ? vielleicht ist das lesen, filtern mit OLEDB besser
    EDIT:
    die Zeile 8 in deinem Code in Post#41

    VB.NET-Quellcode

    1. Dim xlWorkbook As Workbook = xlWorkbooks.Add()

    ist überflüssig, willst ein Tabelle inzufügen ?


    Du hast recht, das habe ich nun rausgeworfen, vielen Dank-

    Zu Deiner Frage:
    Ich bin in einer Firma die seit fast 90 Jahren Handzettel für fortschrittlich hält.
    Vor 11 Jahren habe ich erst mit Excel Makro Konstrukten angefangen, erst Effizenz-Optimierungen für mich selbst, dann stückweise für die gesamte Firma auf kleiner Flamme digitalisiert.
    Vor ca. 1 Jahr bin ich an die (meine) Grenzen von vba gestossen und habe beschlossen, einges (idz alles) in eine sinnvolle vb.net Anwendung mit Datenbank umzusetzen...kurz gesagt ausmisten und neu schreiben.

    Ich habe bis 2011 programmiert ( größtenteils C), aber immer nur in schon vorhandenen Projekten und dort hoch spezialisiert, z.B. SoftBody-Physics-Engines (so eine simple Art von finiten Elementen) oder Shader-Module für Grafikeffekt in D3D für Spiele. Dabei lernt man leider die Grundlagen des Programmierens nicht wirklich, zu 90% setzt man Formeln aus der Physik sinnvoll um, alles pure Mathe, man bewegt sich in einem sehr solitären eigenem Kosmos. Das macht es mir auch so schwer Msdn oder auch die Profis hier im Forum zu verstehen oder mich technisch korrekt auszudrücken.
    Ich habe keinerlei professionelle programmiertechnische Erfahrung, das war immer Hobby oder auf der Arbeit Mittel zum Zweck.

    Meine Firmen-App hat idz.14 z.t. sehr grße VBA-Excel Trümmer ersetzt, die wichtigen Sachen wie die Datenbanken die daraus entstanden sind laufen gut soweit.
    Ich arbeite nun viele kleinere .xlsm auf, um die auch zu integrieren.

    Aktuell baue ich an einem Anwesenheits-Erfassungsmodul.
    Vorlage ist eine seit 2009 geführte (erst xls, dann xlsm) Tabelle mit diversen Funktionen die auch indirekt an unsere Lohnvorbreitung angebunden ist.
    Die Anwesenheits.xlsm umfasst aktuell ca. 130 Tabellelblätter mit abstrus viel Informationen.
    Den Code Teil den ich oben gepostet habe zieht bestimmte Informationen heraus, bereitet Sie auf (so eine Art Sychronisation oder Fehlerkorrektur) und schiebt die Aufbereiteten Daten in eine Datenbank.
    Ich brauche diese Importfunktion nur solange, bis die neue Datenbank alle gwünschten Funktionen kann, danach werde ich den Import nie wieder brauchen, weil dann die vb.net App den Job komplett übernimmt.

    Der frustrierende Part ist einfach erzählt.
    Der zeitlich aufwendigste Teil sind die Importfilter, weil die alten xlsm Dateinen von vielen Benutzern mit eigenen Ideen benutzt und gepflegt wurden und somit sehr chaotisch sind.
    Manche Informationen liegen als Cell.value vor, dann wieder nur Farbwerte oder Unerscheidungen per Fonttyp, sehr chaotisch.
    Das Datenbank-Archiv soll aber sauber sein und genau die Daten beeinhalten und zur Auswertung zur Verfügung stellen, wie Sie in Zukunft dort auch direkt per App eingepflegt werden.

    Das eigentliche Pflege/Edit Modul ist eher Kleinkram, das habe ich in ein paar Tagen geschrieben und getestet.

    VB.NET-Quellcode

    1. ...
    2. xlWb.Save()
    3. xlApp.Quit()
    4. xlApp = Nothing
    5. ...


    Hierzu noch eine Frage: Ich töte (s. Spoiler oben im Post 44) die Excel Prozesse via Task-Kill, weil mich die Taskmanger Leichen von Excel nervten.
    Das ist in meinen Augen notwendig, hast Du damit keine Probleme ?

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Mabbi“ ()

    Mabbi schrieb:

    Ich töte (s. Spoiler oben im Post 44) die Excel Prozesse via Task-Kill, weil mich die Taskmanger Leichen von Excel nervten.
    Ist ein bekanntes Problem, für das es außer dem TaskKill keine Lösung gibt.
    Es sei denn du verzichtest auf Interop.Office und verwendest epplus.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    @Mabbi
    Hierzu noch eine Frage: Ich töte (s. Spoiler oben im Post 44) die Excel Prozesse via Task-Kill, weil mich die Taskmanger Leichen von Excel nervten.
    Das ist in meinen Augen notwendig, hast Du damit keine Probleme ?


    mit Task-kill musst du dir 1000% sicher sein einen Process zu beenden, ich habe schon erlebt das
    jemand der einen Paletten (Europaletten;Einwegpaletten...etc..) Konto bearbeitet hat (ca. 6std lang)
    wegen Inventur, der dortige Hausinterne Programmieren hat einfach diesen Process beendet...nach
    dem Motto ...6std. lang wird kein Mensch diese Datei bearbeitet haben.. und was war Daten für die
    Inventur waren "FUTSCH".
    also frage dich selbst kann ich ohne weiteres mit "Task-Kill" arbeiten? wie kann ich gewährleisten
    bzw. Prüfen on ich diesen bestimmten Task beenden kann!

    zu der anderen Frage..Excel Leichen..
    hast du denn nach der Ursache geforscht? warum gerade bei bestimmten Excel-Dateien
    diese noch als "Leichen" auftauchen.
    Ich empfehle grundsätzlich, wo immer man auf Excel oder das Vorhandensein von Excel verzichten kann, das auch zu tun.
    Man Excel-Dateien wunderbar auch ganz ohne das Produkt überhaupt installiert zu haben, schreiben bzw. erzeugen oder ergänzen.
    Bereits jetzt ist es so, dass in vielen Firmen alles über die Cloud geht und D365 / Office365 Webbasierend eingesetzt wird, da hast du dann ohnehin "dein" Excel nicht mehr auf dem lokalen Rechner, schade aber auch.

    Einige Vorredner hier haben schon EEPlus ins Gespräch gebracht. Ich kenne keine besseres Tool um mit Excel-Dateien zu arbeiten. Es ist schnell, leichter zu programmieren und man hat keine Excel-Leichen im Taskmanager.
    Es gibt allerdings eine Lizenzänderung, da muss man gucken welche Version man haben möchte.
    Beide Versionen lassen sich über NuGet direkt aus der IDE heraus installieren, natürlich immer nur eine von beiden gleichzeitig ;)

    Informationen hierzu:
    Version 4.5.3.3: github.com/JanKallman/EPPlus
    Version >= 5: nuget.org/packages/EPPlus/5.6.3/license

    Nur wenn man auf Excel gar nicht verzichten kann, wenn man zum Beispiel Dateien als Anhang in Excel-Arbeitsblätter einfügen möchte, sollte man Excel ansprechen, am besten via Interop.
    auch dafür gibt es NuGet Pakete.

    Wenn man Excel Prozesse killen will, dann am besten vor dem Aufruf einer Excel-Instanz sich alle vorhandenen Excel-Instanzen (PID's) in einer Liste merken und nach der Aktion beim Kill, diese als nicht zu killen, berücksichtigen.
    Abschliessende Erfolgsmeldung:

    Alles alte VB6 ist raus.

    Letzter Knackpunkt war "Formatcurrency"

    Habe ich mit Hilfe dieses Forumbbeitrags:
    Format: Nachkommastellen
    dann gelöst.
    Kleiner Denkfehler, große Wirkung.

    Gute 2 Wochen als beta durchgetestet und damit gearbeitet, nun sollten alle Bugs die ich reingebaut habe bei der Konvertierung behoben sein.

    Wieder was gelernt...an alle die geholfen haben..großes Danke.

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

    @Mabbi Das geht besser:

    VB.NET-Quellcode

    1. Dim txt = String.Format("{0:c}", Math.Pi)
    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!
    Hi Rod, ich benutz das hier:

    VB.NET-Quellcode

    1. VK1 = CDbl(AlleZeilen(i)(16).Trim).ToString("C2")


    zum Darstellen von Währungen mit 2 Nachkommastellen. (AlleZeilen ist eine List(of String), kommt aus einem externen csv Import)

    Durch diese Warnung:
    "Beim Konvertieren von "String" in "System.IFormatProvider" können Laufzeitfehler auftreten."

    habe ich den thread gefunden (hatte genau den gleichen Fehler gemacht.... probiert einen String in einen formatierten String zu konvertieren).
    Daraus entstand die .tostring Lösung. Deswegen hatte ich den thread verlinkt.


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

    @Mabbi Ich weiß nicht, was in Deinen Variablen steht.
    Wenn Du eine Double Variable hast, geht das so:

    VB.NET-Quellcode

    1. Dim var = Math.PI
    2. Label1.Text = String.Format("{0:c}", var)
    3. Label2.Text = var.ToString("c")
    und feddich.
    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!