Zellen in VB anzeigen

  • VB.NET

Es gibt 56 Antworten in diesem Thema. Der letzte Beitrag () ist von Marc T..

    So, hab das jetzt ausprobiert. Habe es geschafft die zweite Form einzubinden, und sie popt auch in der Exe auf, sobald man auf öffnen klickt.
    Leider zeigt die zweiter Form nichts an. Ich habe zwei Label´s in der zweiten Form erstellt. Einmal label1 und einmal label2.

    Ich habe eine Warnung:

    Quellcode

    1. Warnung 1 "Public Sub New(currentWorksheet As OfficeOpenXml.ExcelWorksheet)" im vom Designer generierten Typ "Excel_test.Form2" sollte die InitializeComponent-Methode aufrufen. D:\Projektarbeit Servicetechniker\Test\Excel test\Excel test\Form2.vb 8 16 Excel test


    Was soll das heißen?

    Edit:

    Habe nun folgenden Code:

    Form2:
    Spoiler anzeigen

    Quellcode

    1. Imports System.IO
    2. Imports OfficeOpenXml
    3. Public Class Form2
    4. Private _CurrentWorksheet As ExcelWorksheet = Nothing
    5. Public Sub New(currentWorksheet As ExcelWorksheet)
    6. _CurrentWorksheet = currentWorksheet
    7. End Sub
    8. Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    9. Label1.Text = Me._CurrentWorksheet.Cells(1, 1).Value ' Werte an der Oberfläche anzeigen
    10. Label2.Text = Me._CurrentWorksheet.Cells(1, 2).Value ' Werte an der Oberfläche anzeigen
    11. 'usw
    12. End Sub
    13. End Class


    FormMain:
    Spoiler anzeigen

    Quellcode

    1. Option Strict On
    2. Imports System.IO
    3. Imports OfficeOpenXml
    4. Public Class FormMain
    5. Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. GetFiles()
    7. End Sub
    8. Private Sub ButtonRefresh_Click(sender As Object, e As EventArgs) Handles ButtonRefresh.Click
    9. ListBoxExcelFiles.Items.Clear()
    10. GetFiles()
    11. End Sub
    12. Private Sub GetFiles()
    13. ListBoxExcelFiles.Items.AddRange(Directory.GetFiles(System.AppDomain.CurrentDomain.BaseDirectory, "*.xl*"))
    14. End Sub
    15. Private Sub ButtonView_Click(sender As Object, e As EventArgs) Handles ButtonView.Click
    16. If ListBoxExcelFiles.SelectedIndex > 0 Then
    17. Dim existingFile = New FileInfo(ListBoxExcelFiles.SelectedItem.ToString())
    18. Try
    19. Using package = New ExcelPackage(existingFile)
    20. Dim workBook As ExcelWorkbook = package.Workbook
    21. If workBook IsNot Nothing Then
    22. If workBook.Worksheets.Count > 0 Then
    23. Dim currentWorksheet As ExcelWorksheet = workBook.Worksheets.First()
    24. Dim form2 As New Form2(currentWorksheet) 'Form 2 instanziieren
    25. form2.ShowDialog()
    26. End If
    27. End If
    28. End Using
    29. Catch ex As Exception
    30. MessageBox.Show(ex.Message)
    31. End Try
    32. Else
    33. MessageBox.Show("Sie haben nichts ausgewählt..")
    34. End If
    35. End Sub
    36. End Class


    Wenn ich nach dem Fehler Google, finde ich keine gescheiten Hilfestellungen :/


    Und nebenbei noch eine Verständnisfrage:

    Mit:

    Quellcode

    1. Public Class FormMain

    erstelle ich ja eine Klasse / Form.
    Warum kann ich keine neue Klasse / Form erstellen, wenn ich die erste mit

    Quellcode

    1. End Class

    geschlossen habe? Also im gleichem Arbeitsblatt. Vom Programmieren von Microcontrollern via Bascom (Basic Programmiersprache) kenne ich das so, dass man lediglich ein Arbeitsblatt hat. Man kann alle Funktionen verschachteln, oder nacheinander abfragen. Da werden die Funktionen immer mit Klammern ({}) geöffnet und geschlossen.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Marc T.“ ()

    Die Fehlermeldung sagt ja eigentlich schon was noch fehlt damit es funktioniert … :D

    Marc T. schrieb:

    sollte die InitializeComponent-Methode aufrufen


    Folgende Methode müsste demnach noch im Konstruktor aufgerufen werden

    VB.NET-Quellcode

    1. Public Sub New(currentWorksheet As ExcelWorksheet)
    2. ' Dieser Aufruf ist für den Designer erforderlich.
    3. InitializeComponent()
    4. Me._CurrentWorksheet = currentWorksheet
    5. End Sub


    Diese Methode initialisiert alle angezeigten Elemente, deshalb wird aktuell auch nichts in der Form angezeigt.



    Dann noch kurz zur Verständnisfrage :D

    Prinzipiell können zwei Klassen in einem "Arbeitsblatt" erstellt werden, nicht aber zwei WindowsForms.

    Schaut man sich ein WindowsForm-Element genau ein sieht man eigentlich ja schon, das es nicht eine Datei ist, sonder drei Dateien. (Code, Design-Elemente und die Ressourcen). Somit dürfte klar sein, warum es nicht funktioniert einfach die eine Datei um eine zweite Form zu erweitern.

    -> MainForm.vb
    -> MainForm.Designer.vb
    -> MainForm.resx

    Auch wenn es bei Klassen geht besser die Finger davon lassen und jede Klasse in eine extra Datei schreiben ist wesentlich sauberer und auch für weitere Entwickler einfacher zu lesen!


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

    Guten Morgen :)

    Vielen Dank schon mal für eure Hilfe!
    Ich habe wieder ein paar Kleinigkeiten gemacht. Jetzt wird das erste Fenster geschlossen, sobald Form2 öffnet.
    Außerdem habe ich eine Checkbox eingefügt, die (wenn aktiviert) auf dem Klick auf ButtonClick eine dritte Form öffnet.
    Das funktioniert auch alles soweit, aber leider kann ich nur in der vorderen Form arbeiten, wenn ich die .exe ausführe.
    Das heißt wenn ich per Checkbox beide neue Formen öffne, steht eine im Vordergrund und lässt sich bedienen, aber die im Hintergrund
    erst wenn ich die vordere geschlossen habe. Voran liegt das?

    Dann noch eine Frage: Wie kann ich den Pfad der Dateien in der Listbox ausblenden?

    Und zur letzten Frage: Geht es, dass ich in der FormMain die Zelle A1 vom ausgewählten Excel-Dokument abfrage, und wenn da eine
    1 drin steht soll Form2 geöffnet werden, und wenn eine 0 drin steht, soll Form3 geöffnet werden. Geht das mit einer IF Funktion?

    Danke schon mal!

    Hier mein aktueller Code:

    Form Main:
    Spoiler anzeigen

    Quellcode

    1. Option Strict On
    2. Imports System.IO
    3. Imports OfficeOpenXml
    4. Public Class FormMain
    5. Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
    6. End Sub
    7. Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    8. GetFiles()
    9. End Sub
    10. Private Sub ButtonRefresh_Click(sender As Object, e As EventArgs) Handles ButtonRefresh.Click
    11. ListBoxExcelFiles.Items.Clear()
    12. GetFiles()
    13. End Sub
    14. Private Sub GetFiles()
    15. ListBoxExcelFiles.Items.AddRange(Directory.GetFiles(System.AppDomain.CurrentDomain.BaseDirectory, "*.xl*"))
    16. End Sub
    17. Private Sub ButtonView_Click(sender As Object, e As EventArgs) Handles ButtonView.Click
    18. If ListBoxExcelFiles.SelectedIndex > 0 Then
    19. Dim existingFile = New FileInfo(ListBoxExcelFiles.SelectedItem.ToString())
    20. Try
    21. Using package = New ExcelPackage(existingFile)
    22. Dim workBook As ExcelWorkbook = package.Workbook
    23. If workBook IsNot Nothing Then
    24. If workBook.Worksheets.Count > 0 Then
    25. Me.Hide()
    26. If CheckBox1.Checked = True Then
    27. Messprotokoll.Show()
    28. End If
    29. Dim currentWorksheet As ExcelWorksheet = workBook.Worksheets.First()
    30. Dim form2 As New Form2(currentWorksheet) 'Form 2 instanziieren
    31. form2.ShowDialog()
    32. End If
    33. End If
    34. End Using
    35. Catch ex As Exception
    36. MessageBox.Show(ex.Message)
    37. End Try
    38. Else
    39. MessageBox.Show("Sie haben nichts ausgewählt..")
    40. End If
    41. End Sub
    42. End Class

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marc T.“ ()

    Marc T. schrieb:

    Woran liegt das?

    -> Das liegt daran das die zweite Form mit einem "ShowDialog" aufgerufen wird, dieser Aufruf blockiert den Aufrufer bis die Aufgerufene Form wieder geschlossen wird mit "Show" wird der Aufrufer nicht blockiert ...

    Um automatisch Form2 zu öffnen wenn A1 einen gewissen Wert hat, muss eine For Each Schleife nach dem laden der Excel Files durchlaufen werden. In dieser kann wie schon richtig vermutet über eine IF-Abfrage entschieden werden ob die Bedingung erfüllt wird oder nicht.

    Ich kann voraussichtlich heute Abend noch ein kleines Bsp. dazu erstellen ...
    Das war ja einfach :D
    Funktioniert.
    Das wäre super! Ich probiere das bis heute Abend mal selbst, vielleicht bekomme ich es ja hin :)


    Edit:

    MrNobody schrieb:

    Ich kann voraussichtlich heute Abend noch ein kleines Bsp. dazu erstellen ...


    Brauchst das nicht mehr machen, ich habe eine andere Lösung gefunden :)
    Wenn ich weiterhin Hilfe brauche, sage ich bescheid.
    Danke trotzdem! :)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marc T.“ ()

    Morgen :)

    Also dein Beispiel hilft mir schon mal sehr!! Da du da alles schön beschrieben hast, verstehe ich das endlich langsam.
    Nur folgendes klappt noch nicht:

    MrNobody schrieb:

    Marc T. schrieb:

    Wie mache ich das mit einer dritten Form?

    Genau das gleiche wie mit Form 2 nur die Klasse entsprechend umbenennen

    VB.NET-Quellcode

    1. ​Dim FormXY as New FormXY() '...


    Ich will aus der zweiten oder dritten Form eine vierte öffnen, die auf das gleiche Exelworksheet zugreift. Wenn ich das über die erste Form mache (so wie bei dir), dann geht das. Aber jetzt muss ich das irgendwie Formübergreifend hin bekommen. Wie geht das?

    Ich habe auch schon probiert bei deinem Beispiel in die dritte Form zu schreiben, dass beim klick auf das Label eine 4. Form geöffnet wird, welche auch auf das ursprüngliche ExcelWorkSheet zugreift, leider ohne Erfolg :/

    Wie macht man das?

    Marc T. schrieb:

    Aber jetzt muss ich das irgendwie Formübergreifend hin bekommen. Wie geht das?
    Gib der Form eine entsprechende Property, die Du vor dem ShowWindow()-Befehl mit der betreffenden Instanz belegst.
    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!

    RodFromGermany schrieb:

    Gib der Form eine entsprechende Property, die Du vor dem ShowWindow()-Befehl mit der betreffenden Instanz belegst.

    Oder auch hier wieder das Exelworksheet im Konstruktor mit übergeben ...

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports OfficeOpenXml
    2. Public Class Form2
    3. Private _CurrentWorksheet As ExcelWorksheet
    4. Public Sub New(currentWorksheet As ExcelWorksheet)
    5. ' Dieser Aufruf ist für den Designer erforderlich.
    6. InitializeComponent()
    7. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    8. Me._CurrentWorksheet = currentWorksheet
    9. End Sub
    10. Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
    11. Dim form4 As New Form4(Me._CurrentWorksheet)
    12. form4.Show()
    13. End Sub
    14. End Class



    >>Auch wenn man sich das mit dem Klick auf das Label zweimal überlegen sollte, da ein Label eigentlich nur zum anzeigen gedacht ist! :D <<

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

    @Marc.T: Ich sehe, Mr.Nobody hat dir eine Vorlage geliefert, bei der die VB-Voreinstellungen extrem ungünstig sind.

    Er selbst tappt in seim Code deswegen nicht in die Fussfallen, die das eröffnet :thumbup: .
    Aber dir würde ich sehr empfehlen, die VB-Voreinstellungen zu korrigieren, und zwar projektweit, und auch als Voreinstellung des VisualStudios, damit auch neu angelegte Projekte von dieser Seuche frei sind.
    Visual Studio - Empfohlene Einstellungen

    Ich nenne die ungünstigen VB-Voreinstellungen die "Deppen-Einstellungen", denn durch scheinbare Bequemlichkeiten verhindern sie, dass man Konzept, Systematik und Denkweise von OOP und des .Net-Frameworks tiefer versteht.
    Insbesondere das Konzept "Datentyp" muss einem so gut wie verborgen bleiben, wenn man auf einem System entwickelt, wo im Hintergrund jeder Datentyp in jeden anderen umgewandelt wird.
    Also mein Tipp: Stell dein System richtig ein, dann lernst du ungleich schneller programmieren.
    Jetzt habe ich es gecheckt..

    Das habe ich vorher schon genau so gemacht, aber da kam immer der Fehler:

    Quellcode

    1. Fehler 1 Zu viele Argumente für "Public Sub New()". C:\Users\marc.timmermann\Desktop\Test\Test\Form2.vb 17 32 Test


    Hab ganz vergessen das ich Form4 ja nicht leer stehen lassen darf :D
    Ist beseitigt und funktioniert! Danke!

    Edit: Das mit dem öffnen durch klick auf das Label ist nur testweise gewesen...


    Edit#2:
    @ErfinderDesRades
    Schaue ich mir sofort an! Danke!


    Unnötiges Vollzitat entfernt
    -Artentus

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

    Marc T. schrieb:

    aber da kam immer der Fehler
    Wenn Du die Parameter einer Prozedur änderst, musst Du immer 2 Seiten ändern.
    Einmal den Aufrufer, der den (neuen) Parameter übergeben soll
    und
    den Aufgerufenen, der den Parameter verarbeiten soll.
    @MrNobody Es ist nicht unbedingt gut, im Konstruktor einer Form Parameter zu übergeben, da der Designer für sich gern einen parameterlosen Konstruktor haben möchte.
    Und wenn Du die Wahl zwischen zwei Konstruktoren hast, nimmst Du schnell mal den falschen.
    Also: Obicht. ;)
    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!

    ErfinderDesRades schrieb:

    Er selbst tappt in seim Code deswegen nicht in die Fussfallen, die das eröffnet .

    @ErfinderDesRades naja in "Form1" ist Option Strict On ja immerhin separat deklariert :D , ich bevorzuge diese Variante, da es einem so noch einmal explizit beim öffnen der Klasse ins Auge sticht ob es sich um Option Strict ON oder OFF handelt.(Eine Solution mit zig Projekten aus mehrer Jahren Programmierung, in denen nicht immer auf Option Strict ON geachtet wurde ... :whistling: ) Aber im Prinzip stimmt es schon sollte man eigentlich drauf achten ...

    RodFromGermany schrieb:

    Es ist nicht unbedingt gut, im Konstruktor einer Form Parameter zu übergeben, da der Designer für sich gern einen parameterlosen Konstruktor haben möchte.Und wenn Du die Wahl zwischen zwei Konstruktoren hast, nimmst Du schnell mal den falschen.

    @RodFromGermany naja dieser Sorge lässt sich ja einfach aus dem Weg gehen in dem man einfach innerhalb des mit Parameter-bestückten Konstruktors die InitializeComponent() - Methode aufruft, somit steht der Standard Konstruktor gar nicht mehr zur Verfügung ... Klar können die Parameter auch über eine Property gesetzt werden aber gerade bei "zwingend nötigen" Parameter, kann man so verhindern das sie vergessen werden!

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

    MrNobody schrieb:

    die InitializeComponent() - Methode aufruft
    Es kann passieren, dass Du diese Form im Designer nicht angezeigt bekommst :!:
    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!
    Mal ne Frage zwischendurch:

    Ich will in eine Form mehrere Comboboxen einfügen, die alle immer mit den gleichen Wörtern ausgestattet werden.
    Quasi so:

    Quellcode

    1. ComboBox1.Items.Add("Gut")
    2. ComboBox1.Items.Add("Mittel")
    3. ComboBox1.Items.Add("Schlecht")
    4. ComboBox2.Items.Add("Gut")
    5. ComboBox2.Items.Add("Mittel")
    6. ComboBox2.Items.Add("Schlecht")
    7. ComboBox3.Items.Add("Gut")
    8. ComboBox3.Items.Add("Mittel")
    9. ComboBox3.Items.Add("Schlecht")


    Wie ihr seht ist diese Methode sehr umständlich...
    Kann ich das irgendwie so machen:

    Quellcode

    1. Dim zustand(9) As System.Object
    2. Dim i As Integer
    3. For i = 0 To 9
    4. zustand(i) = "Zustand " & i
    5. Next i
    6. ComboBox1.Items.AddRange(zustand)


    Nur statt 0 bis 9 verschiedene Wörter einsetzen?
    Von Microkontrollern kenne ich das, dass man dann schreibt

    Quellcode

    1. Dim i As Word
    usw..
    Funktioniert hier leider nicht :(

    Marc T. schrieb:

    sehr umständlich
    Jou. Mach es so:

    VB.NET-Quellcode

    1. Dim texte() = {"Gut", "Mittel", "Schlecht"}
    2. ComboBox1.Items.AddRange(texte)
    3. ComboBox2.Items.AddRange(texte)
    4. ComboBox3.Items.AddRange(texte)
    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!
    Eine Möglichkeit wäre das hier

    VB.NET-Quellcode

    1. Me.ComboBox1.Items.AddRange(New String() {"tri", "tra", "tru"})
    2. 'Oder so bei mehreren ComboBoxen
    3. Dim Items As String() = {"tri", "tra", "tru"}
    4. Me.ComboBox1.Items.AddRange(Items)
    5. Me.ComboBox2.Items.AddRange(Items)


    -> Schau die bei solchen Problemen bei Gelegenheit immer die Properties eines Control's an, und lese dir die Beschreibungen davon durch, das .NET Framework bietet hier einiges an Möglichkeiten von Haus aus ...

    Edit: Da war RodFromGermany schneller ^^