VBA-Script to C#-Script probleme beim übersetzen

  • C#

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von newsletter.

    VBA-Script to C#-Script probleme beim übersetzen

    Moin,

    Ich habe folgenden VBA-Code, welcher eine Word-Tabelle befüllt.
    Hat Textbox.Text links einen Wert, soll es die Linke und Rechte Spalte in die Tabelle übernehmen.
    Siehe Bild-->


    Visual Basic-Quellcode

    1. Dim Nr As String
    2. Dim Arr As Variant
    3. Dim P As String
    4. Dim Arra As Variant
    5. If Len(txtNr1.Text) > 0 Then
    6. Nr = txtNr1.Text & Chr$(255)
    7. P = txtP1.Text & Chr$(255)
    8. End If
    9. If Len(txtNr2.Text) > 0 Then
    10. Nr = Nr & txtNr2.Text & Chr$(255)
    11. P = P & txtP2.Text & Chr$(255)
    12. End If
    13. If Len(txtNr3.Text) > 0 Then
    14. Nr = Nr & txtNr3.Text & Chr$(255)
    15. P = P & txtP3.Text & Chr$(255)
    16. End If
    17. If Len(Nr) > 0 Then
    18. Arr = Split(Nr, Chr$(255), , vbBinaryCompare)
    19. Arra = Split(P, Chr$(255), , vbBinaryCompare)
    20. Select Case UBound(Arr)
    21. Case 1
    22. With ActiveDocument.Tables(1) '1.Zeile
    23. .Rows(1).Cells(1).Range.Text = Arr(0)
    24. .Rows(1).Cells(2).Range.Text = Arra(0)
    25. End With
    26. Case 2
    27. With ActiveDocument.Tables(1)
    28. .Rows(1).Cells(1).Range.Text = Arr(0)
    29. .Rows(2).Cells(1).Range.Text = Arr(1)
    30. .Rows(1).Cells(2).Range.Text = Arra(0)
    31. .Rows(2).Cells(2).Range.Text = Arra(1)
    32. End With
    33. Case 3
    34. With ActiveDocument.Tables(1)
    35. .Rows(1).Cells(1).Range.Text = Arr(0)
    36. .Rows(2).Cells(1).Range.Text = Arr(1)
    37. .Rows(3).Cells(1).Range.Text = Arr(2)
    38. .Rows(1).Cells(2).Range.Text = Arra(0)
    39. .Rows(2).Cells(2).Range.Text = Arra(1)
    40. .Rows(3).Cells(2).Range.Text = Arra(2)
    41. End With
    42. End Select


    Nun soll dieser aber in C# funktionieren... soweit bin ich bereits:

    C#-Quellcode

    1. string Nr = "";
    2. Object Arr;
    3. Dim P As String;
    4. Object Arra;
    5. if (L1.Text.Length > 0)
    6. {
    7. Nr = L1.Text + (Char)255;
    8. Arr = R1.Text + (Char)255;
    9. }
    10. if (L2.Text.Length > 0)
    11. {
    12. Nr = L2.Text + (Char)255;
    13. Arr = R2.Text + (Char)255;
    14. }
    15. if (L3.Text.Length > 0)
    16. {
    17. Nr = L3.Text + (Char)255;
    18. Arr = R3.Text + (Char)255;
    19. }


    Hoffe mir kann hier jemand helfen, da das so ziemlich der wichtigste Teil ist...

    Danke für jede Hilfe!

    Gruss Newsletter

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

    Hi,

    ich weiß, es ist nicht C#, aber beim Übertragen von VBA-Projekten nehme ich lieber VB.NET. Das geht ganz gut, wie du siehst habe ich große Teile deines VBA-Code übernehmen können. Vielleicht hilft es dir, dein Projekt in C# umzuwandeln.

    Viel Erfolg und happy hackin'
    :)







    VB.NET-Quellcode

    1. 'Benötigt Verweis auf die COM-Schnittstelle "Microsoft Word Object Library"
    2. Imports Word = Microsoft.Office.Interop.Word
    3. Public Class Form1
    4. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    5. Dim Nr As String
    6. Dim Arr() As String
    7. Dim P As String
    8. Dim Arra() As String
    9. ' Word laden
    10. Dim Wordapp As New Word.Application
    11. Dim Doc As Word.Document
    12. Dim Rng As Word.Range
    13. 'Word-Dokument anzeigen
    14. Wordapp.Visible = True
    15. Doc = Wordapp.Documents.Add
    16. 'Tabelle vorbereiten
    17. Rng = Doc.Range(Start:=0, End:=0)
    18. Rng.Tables.Add(Range:=Doc.Paragraphs.Item(1).Range,
    19. NumRows:=3, NumColumns:=2)
    20. 'Hier folgt größenteils dein Code
    21. If Len(txtNr1.Text) > 0 Then
    22. Nr = txtNr1.Text & Chr(255)
    23. P = txtP1.Text & Chr(255)
    24. End If
    25. If Len(txtNr2.Text) > 0 Then
    26. Nr = Nr & txtNr2.Text & Chr(255)
    27. P = P & txtP2.Text & Chr(255)
    28. End If
    29. If Len(txtNr3.Text) > 0 Then
    30. Nr = Nr & txtNr3.Text & Chr(255)
    31. P = P & txtP3.Text & Chr(255)
    32. End If
    33. If Len(Nr) > 0 Then
    34. Arr = Split(Nr, Chr(255), , vbBinaryCompare)
    35. Arra = Split(P, Chr(255), , vbBinaryCompare)
    36. Select Case UBound(Arr)
    37. Case 1
    38. With Doc.Tables(1) '1.Zeile
    39. .Rows(1).Cells(1).Range.Text = Arr(0)
    40. .Rows(1).Cells(2).Range.Text = Arra(0)
    41. End With
    42. Case 2
    43. With Doc.Tables(1)
    44. .Rows(1).Cells(1).Range.Text = Arr(0)
    45. .Rows(2).Cells(1).Range.Text = Arr(1)
    46. .Rows(1).Cells(2).Range.Text = Arra(0)
    47. .Rows(2).Cells(2).Range.Text = Arra(1)
    48. End With
    49. Case 3
    50. With Doc.Tables(1)
    51. .Rows(1).Cells(1).Range.Text = Arr(0)
    52. .Rows(2).Cells(1).Range.Text = Arr(1)
    53. .Rows(3).Cells(1).Range.Text = Arr(2)
    54. .Rows(1).Cells(2).Range.Text = Arra(0)
    55. .Rows(2).Cells(2).Range.Text = Arra(1)
    56. .Rows(3).Cells(2).Range.Text = Arra(2)
    57. End With
    58. End Select
    59. End If
    60. End Sub
    61. End Class
    Bilder
    • VBP.PNG

      17,25 kB, 781×259, 465 mal angesehen
    Hallo
    Hier ist mein Vorschlag, mit Schleifen und einem Dictionary.

    VB.NET-Quellcode

    1. 'Benötigt Verweis auf die COM-Schnittstelle "Microsoft Word Object Library"
    2. Imports Word = Microsoft.Office.Interop.Word
    3. Public Class Form1
    4. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    5. ' Word laden
    6. Dim Wordapp As New Word.Application
    7. Dim Doc As Word.Document
    8. Dim Rng As Word.Range
    9. 'Word-Dokument anzeigen
    10. Wordapp.Visible = True
    11. Doc = Wordapp.Documents.Add
    12. 'Tabelle vorbereiten
    13. Rng = Doc.Range(0, 0) '(Start, End)
    14. Rng.Tables.Add(Range:=Doc.Paragraphs.Item(1).Range, NumRows:=3, NumColumns:=2) '(Range, NumRows, NumColumns)
    15. 'Hier folgt größenteils dein Code
    16. Dim Texte As New Dictionary(Of String, String)
    17. For x As Integer = 1 To 3
    18. If Me.Controls("txtNr" & x.ToString).Text.Trim.Length > 0 Then
    19. Texte.Add(Me.Controls("txtNr" & x.ToString).Text.Trim, Me.Controls("txtP" & x.ToString).Text.Trim)
    20. End If
    21. Next
    22. Dim Zaehler As Integer = 1
    23. For Each TextItem As KeyValuePair(Of String, String) In Texte
    24. With Doc.Tables(1)
    25. .Rows(Zaehler).Cells(1).Range.Text = TextItem.Key
    26. .Rows(Zaehler).Cells(2).Range.Text = TextItem.Value
    27. End With
    28. Zaehler += 1
    29. Next
    30. End Sub
    31. End Class
    Ohgott... mir ist das viel zu kompliziert ?( ich begreife noch nichtmal den VBA-Code...

    Wie sieht sowas in C# aus?
    Bin ziemlich abhängig von diesem Teilprogramm :S Ohne diesen komplizierten Teil kann ich nicht weitermachen :(

    evtl. wenns geht mit Beschreibung, damit ich das nicht nur einfach Copy&Paste mache sondern auch begreife ?(
    Der Code mach eigentlich genau das, was du im ersten Post geschrieben hast. Nur über ein paar Umwegen
    Hier eine Kurze Erklärung.
    Er überprüft die Textboxen "txtNr1","txtNr2" und "txtNr3" ob Text drin steht.
    Falls Ja, kombiniert er die Texte der Textboxen "txtNr" in die Variable "NR" und die Texte der Textboxen "txtP" in die Variable "P".
    Danach teilt er die Variable "NR" wieder in einzelne Texte auf und speichert sie in den Array "Arr".
    Das Gleiche macht er mit der Variable "P" in den Array "Arrra".
    Danach schreibt er den Inhalt der beiden Arrays in die Word-Tabelle.

    Nach nochmaligen anschauen, gibt es sogar einen noch effizienteren weg das Gewünschte zu erreichen.
    Man kann die beiden Schlaufen kombinieren und das Dictionary eliminieren.
    1. Überprüfen ob in der linken Textbox ("txtNr1","txtNr2" und "txtNr3") Text drin steht.
    2. Falls Ja, Text in Word-Tabelle schreiben.
    Der Code dazu sieht in etwa so aus:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Windows.Forms;
    3. using Word = Microsoft.Office.Interop.Word;

    C#-Quellcode

    1. private void button1_Click(object sender, EventArgs e)
    2. {
    3. //Word laden
    4. Word.Application Wordapp = new Word.Application();
    5. //Word anzeigen
    6. Wordapp.Visible = true;
    7. //Word Dokument erstellen
    8. Word.Document Doc = Wordapp.Documents.Add();
    9. //Tabelleeinfügestelle definieren
    10. Word.Range Rng = Doc.Range(0, 0); //(Start, End)
    11. //Tabelle einfügen
    12. Rng.Tables.Add(Doc.Paragraphs[1].Range, 3, 2); //(Range, NumRows, NumColumns)
    13. //Zähler Definieren
    14. int Zaehler = 1;
    15. //dynamisches einlesen der Werte aus den Textboxen mit einer Schleife (3 Durchläufe)
    16. for (int x = 1; x <= 3; x++)
    17. {
    18. //Abfrage ob in den Textboxen "txtNr" etwas geschrieben steht
    19. //erster Durchlauf: if (txtNr1.Text.Trim().Length > 0)
    20. //zweiter Durchlauf: if (txtNr2.Text.Trim().Length > 0)
    21. //-> in deinem Bsp. wird dieser übersprungen weil Textlänge von txtNr2 = 0
    22. //dritter Durchlauf: if (txtNr3.Text.Trim().Length > 0)
    23. if (this.Controls["txtNr" + x.ToString()].Text.Trim().Length > 0)
    24. {
    25. //erster Durchlauf/erstes Element: txtNr-Wert in Zeile 1 und Spalte 1 schreiben
    26. //dritter Durchlauf/zweites Element: txtNr-Wert in Zeile 2 und Spalte 1 schreiben
    27. Doc.Tables[1].Rows[Zaehler].Cells[1].Range.Text = this.Controls["txtNr" + x.ToString()].Text.Trim();
    28. //erster Durchlauf/erstes Element: txtP-Wert in Zeile 1 und Spalte 2 schreiben
    29. //dritter Durchlauf/zweites Element: txtP-Wert in Zeile 2 und Spalte 2 schreiben
    30. Doc.Tables[1].Rows[Zaehler].Cells[2].Range.Text = this.Controls["txtP" + x.ToString()].Text.Trim();
    31. //Zähler um 1 erhöhen
    32. Zaehler += 1;
    33. }
    34. }
    35. }

    newsletter schrieb:

    Ohgott... mir ist das viel zu kompliziert ich begreife noch nichtmal den VBA-Code...

    Wenn man einen Code, den man weder versteht noch die Funktionsweise halbwegs erraten kann, versucht in eine andere Sprache einzubringen - kann das nur schief gehen.

    Bitte versuche zunächst den VBA-Code größtenteils zu verstehen.
    Hilfe? Gibt es recht wenig dazu zu sagen, das Programm wird nach einer geregelten Struktur ausgeführt, also kannst du es dir auch in dieser Struktur anschauen (Zeile für Zeile) und die für dich unverständlichen Befehle googlen o.ä.

    Wenn du dann den Ablauf und das Vorgehen des VBA-Codes verstanden hast, ist das Umsetzen in C# oder VB.NET oder sonstwas einfacher. Und ab dann kannst du auch auf die geposteten Snippets zurückgreifen und - welch Wunder - das selbe Spiel wiederholen.

    LG, Acr0most
    Wenn das Leben wirklich nur aus Nullen und Einsen besteht, dann laufen sicherlich genügen Nullen frei herum. :D
    Signature-Move 8o
    kein Problem mit privaten Konversationen zu Thema XY :thumbup:
    Moin,

    Vielen Dank für eure Hilfe!

    Bei mir kommt jedesmal beim Compilieren der Fehler:

    C#-Quellcode

    1. System.NullReferenceException: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."


    woran kann das liegen?

    Habe nun versucht dein Code 1:1 zu übernehmen um anschliessend die Funktionsweise nachvollziehen zu können..

    sieht so aus:

    C#-Quellcode

    1. private void CmdTest_Click(object sender, EventArgs e)
    2. {
    3. //Word laden
    4. Word.Application Wordapp = new Word.Application();
    5. //Word anzeigen
    6. Wordapp.Visible = true;
    7. //Word Dokument erstellen
    8. Word.Document Doc = Wordapp.Documents.Add();
    9. //Tabelleeinfügestelle definieren
    10. Word.Range Rng = Doc.Range(0, 0); //(Start, End)
    11. //Tabelle einfügen
    12. Rng.Tables.Add(Doc.Paragraphs[1].Range, 3, 2); //(Range, NumRows, NumColumns)
    13. int Zaehler = 1;
    14. for (int x = 1; x <= 3; x++)
    15. {
    16. if (this.Controls["txtNr" + x.ToString()].Text.Trim().Length > 0)
    17. {
    18. Doc.Tables[1].Rows[Zaehler].Cells[1].Range.Text = this.Controls["txtNr" + x.ToString()].Text.Trim();
    19. Doc.Tables[1].Rows[Zaehler].Cells[2].Range.Text = this.Controls["txtP" + x.ToString()].Text.Trim();
    20. Zaehler += 1;
    21. }
    22. }
    23. }


    txtNr
    txtNr1
    txtNr2
    txtNr3
    txtP
    txtP1
    txtP2
    txtP3
    existieren...



    @Acr0most
    Hier ist mein Problem beim VBA-Code, was ist Chr(255)? wieso wird dieser überall dazugemacht?
    wofür steht "vbBinaryCompare"?
    Der Rest ist ziemlich selbsterklärend

    Visual Basic-Quellcode

    1. [...]
    2. Nr = Nr & txtNr3.Text & Chr(255)
    3. P = P & txtP3.Text & Chr(255)
    4. [...]
    5. Arr = Split(Nr, Chr(255), , vbBinaryCompare)
    6. Arra = Split(P, Chr(255), , vbBinaryCompare)
    7. Select Case UBound(Arr)

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

    google: "VBA chr" -> suchen -> Treffer

    google: "VBA vbBinaryCompare" -> suchen -> Treffer
    Wenn das Leben wirklich nur aus Nullen und Einsen besteht, dann laufen sicherlich genügen Nullen frei herum. :D
    Signature-Move 8o
    kein Problem mit privaten Konversationen zu Thema XY :thumbup:
    Die NullReferenceException konnte ich nur nachvollziehen, als ich keine Textboxen mit den Namen txtNr1, txtNr2, txtNr3, txtP1, txtP2 und txtP3 auf der Form hatte.
    Ich hänge hier einmal mein Test-Projekt an, vielleicht hilft es dir weiter.
    Dateien

    HenryV schrieb:

    Die NullReferenceException konnte ich nur nachvollziehen, als ich keine Textboxen mit den Namen txtNr1, txtNr2, txtNr3, txtP1, txtP2 und txtP3 auf der Form hatte.
    Ich hänge hier einmal mein Test-Projekt an, vielleicht hilft es dir weiter.


    Hallo, vielen Dank für deine Rückmeldung.

    Ich habe das gesendete Projekt getestet. Es hat einwandfrei funktioniert.
    Danach 1:1 nachgestellt und auch dort hat es funktioniert.

    Nur bei meinem Hauptprogramm, in dem ich das gerne haben möchte gibt es diesen Fehler.
    Wenn ich es dort 1:1 übernehme und teste klappt das ganze nicht keine Ahnung wieso...

    Er hängt jedesmal hier:

    C#-Quellcode

    1. if (this.Controls["txtNr" + x.ToString()].Text.Trim().Length > 0) //<====HIER
    2. {
    3. //erster Durchlauf/erstes Element: txtNr-Wert in Zeile 1 und Spalte 1 schreiben
    4. //dritter Durchlauf/zweites Element: txtNr-Wert in Zeile 2 und Spalte 1 schreiben
    5. Doc.Tables[1].Rows[Zaehler].Cells[1].Range.Text = this.Controls["txtNr" + x.ToString()].Text.Trim();
    6. //erster Durchlauf/erstes Element: txtP-Wert in Zeile 1 und Spalte 2 schreiben
    7. //dritter Durchlauf/zweites Element: txtP-Wert in Zeile 2 und Spalte 2 schreiben
    8. Doc.Tables[1].Rows[Zaehler].Cells[2].Range.Text = this.Controls["txtP" + x.ToString()].Text.Trim();
    9. //Zähler um 1 erhöhen
    10. Zaehler += 1;
    11. }


    Fehlermeldung:

    C#-Quellcode

    1. System.NullReferenceException: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."


    Using's:

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Data;
    5. using System.Drawing;
    6. using System.Linq;
    7. using System.Text;
    8. using System.Threading.Tasks;
    9. using System.Windows.Forms;
    10. using Word = Microsoft.Office.Interop.Word;
    11. using System.Reflection;
    12. using System.Data.OleDb;
    13. using System.Diagnostics;


    C#-Quellcode

    1. public FrmBlub()
    2. {
    3. InitializeComponent();
    4. ToolStrLabel.ForeColor = System.Drawing.Color.Green;
    5. PanMA.Visible = false;
    6. PanManuell.Visible = false;
    7. PanDrucken.Visible = false;
    8. PanKInfo.Visible = false;
    9. PanManuell.Enabled = false;
    10. //Toolhelp-Control
    11. ToolHelp();
    12. StaStrip.Text = "Keine Funktion ausgeführt";
    13. TxtTelPw.Text = txtNachname.Text;
    14. Lohninitialisierung();
    15. }
    16. private void Lohninitialisierung()
    17. {
    18. //Initialisierung
    19. ComAnsprache.Items.Add("Herr");
    20. ComAnsprache.Items.Add("Frau");
    21. ComAnsprache.SelectedIndex = 0;
    22. //Addiere Ranges Jan-Dez
    23. ComMonat.Items.AddRange(new string[] { "Januar", "Februar" , "März", "April",
    24. "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" });
    25. //Selected Month
    26. ComMonat.SelectedItem = DateTime.Now.ToString("MMMM");
    27. DateTime Time = DateTime.Now;
    28. var minuseins = Time.AddYears(-1);
    29. ComJahr.Items.Add(minuseins.Year);
    30. ComJahr.Items.Add(Time.Year);
    31. var eins = Time.AddYears(1);
    32. ComJahr.Items.Add(eins.Year);
    33. var zwei = Time.AddYears(2);
    34. ComJahr.Items.Add(zwei.Year);
    35. ComJahr.SelectedItem = Time.Year;
    36. }
    37. private void ToolHelp()
    38. {
    39. ToolTip mytool = new ToolTip();
    40. mytool.SetToolTip(ComAnsprache, "Geschlechtangabe");
    41. mytool.IsBalloon = true;
    42. mytool.SetToolTip(txtBrutto, "Bruttolohnangabe");
    43. mytool.IsBalloon = true;
    44. }

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

    hast du unter this ein Control namens txtNr + x.ToString() ?
    Ist X ggf. leer/null/etwas anders als das was du erwartest?

    Hat das Control auf das du das zugreifst eine .Text - Methode?
    Oder hast du mehrere Controls gleich benannt und es geht deshalb nicht?

    Bitte mal alles überprüfen und nochmal Feedback geben.

    Lg, Acr0most
    Wenn das Leben wirklich nur aus Nullen und Einsen besteht, dann laufen sicherlich genügen Nullen frei herum. :D
    Signature-Move 8o
    kein Problem mit privaten Konversationen zu Thema XY :thumbup:
    So wie ich im Bild in deinem Post #7 zu Erkennen glaube, sind deine Textboxen in einer GroupBox.
    Mein Code funktioniert nur wenn die Textboxen direkt auf der Form sind.
    Somit musst du den Pfad zum Control im Code anpassen.
    Aus der Zeile

    C#-Quellcode

    1. if (this.Controls["txtNr" + x.ToString()].Text.Trim().Length > 0)
    wird dann z.B.

    C#-Quellcode

    1. if (this.groupBox1.Controls["txtNr" + x.ToString()].Text.Trim().Length > 0)
    oder du lässt nach dem Control suchen (Es wird das erste genommen, welches dem Suchtext entspricht.)

    C-Quellcode

    1. if (this.Controls.Find("txtNr" + x.ToString(), true)[0].Text.Trim().Length > 0)

    Dir anderen Zeilen müssen dann aber auch angepasst werden.
    VIELEN DANK für deine Hilfe!

    Das Programm funktioniert nun einwandfrei :thumbup: es lag tatsächlich nur an der Groupbox:

    C#-Quellcode

    1. if (this.GrpLieferschein.Controls.Find("txtNr" + x.ToString(), true)[0].Text.Trim().Length > 0)
    2. {
    3. myDoc.Tables[1].Rows[Zaehler].Cells[1].Range.Text = GrpLieferschein.Controls["txtNr" + x.ToString()].Text.Trim();
    4. ...
    5. }


    Gruss Newsletter