VBA in C# Übersetzen - Prüfen von Excel Zellen, Übergeben in Methode Wie?

  • C#

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von dani02.

    VBA in C# Übersetzen - Prüfen von Excel Zellen, Übergeben in Methode Wie?

    Hallo Leute,

    zurzeit übersetze ich mein VBA Code in C# und stehe des Öfteren vor mehr oder wenigen großen Schwierigkeiten aber hier fehlt
    mir nun jegliche Fantasie ?(

    Ich habe ein VBA Code der mir überprüft, ob eine Zelle ein Datum ist und ob dieser in der gewünschten Kalenderwoche liegt.
    In VBA habe ich eine Funktion die dann aufgerufen wird (KalenderwocheNachDin) die eben schaut, ob diese Zelle im jeweiligen Bereich liegt und danach erfolgen weitere Aktionen.

    Mein Problem ist nun wie ich das selbige in C# umwandle, ich habe zwar den Code der mir die aktuelle KW errechnet aber wie übergebe ich dieser Methode eine Zelle, sodass es wie in VBA automatisch erkennt ob es die oder jene KW ist?

    Zum Verständnis füge ich mein VBA Code an, sowie auch mein C# Code, hoffe ihr könnt mir weiter helfen.

    Funktion Kalenderwoche VBA:

    Quellcode

    1. Function KalenderwocheNachDin(dat As Date) As Integer
    2. Dim a As Integer
    3. a = Int((dat - DateSerial(Year(dat), 1, 1) + ((Weekday(DateSerial(Year(dat), 1, 1)) + 1) Mod 7) - 3) / 7) + 1
    4. If a = 0 Then
    5. a = KalenderwocheNachDin(DateSerial(Year(dat) - 1, 12, 31))
    6. ElseIf a = 53 And (Weekday(DateSerial(Year(dat), 12, 31)) - 1) Mod 7 <= 3 Then
    7. a = 1
    8. End If
    9. KalenderwocheNachDin = a
    10. End Function


    Funktion wo mittels VBA aufgerufen wird:

    Quellcode

    1. For i = 13 To 1044
    2. 'ws_anfang.Cells(i, 19).value muss an funktion zum umwandeln gegeben werden
    3. If IsDate(ws_anfang.Cells(i, 19).value) = True Then
    4. If KalenderwocheNachDin(ws_anfang.Cells(i, 19).value) = KalenderwocheNachDin(Date) And Year(ws_anfang.Cells(i, 19).value) = Year(Date) Or KalenderwocheNachDin(ws_anfang.Cells(i, 20).value) = KalenderwocheNachDin(Date) And Year(ws_anfang.Cells(i, 20).value) = Year(Date) Then
    5. //hier passiert was
    6. End If
    7. End If
    8. Next i


    Meine C# KW Methode:

    Quellcode

    1. static int Kalenderwoche()
    2. {
    3. DateTime dt = DateTime.Now;
    4. System.Globalization.Calendar objCal = CultureInfo.CurrentCulture.Calendar;
    5. int weekofyear = objCal.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    6. // return weekofyear;
    7. return weekofyear;
    8. }


    Mein versuch zum Übersetzen:

    Quellcode

    1. for (i = 13; i <= 1044; i++)
    2. {
    3. try
    4. {
    5. // System.DateTime dt = System.DateTime.Parse(ws_anfang.Cells[i, 19].value);
    6. if (Kalenderwoche(ws_anfang.Cells[i,19].value));
    7. {
    8. exApp.DisplayAlerts = true;
    9. exApp.DisplayAlerts = false;
    10. }
    11. }
    12. catch
    13. {
    14. }
    15. }
    Hallo @dani02!

    Als erstes einmal: Bist du dir sicher, dass du VBA (Visual Basic for Appication) oder VB.NET (Visual Basic .NET) meinst?
    Unterschied: VBA ist in Office integriert, VB.NET ist eine eigenständige Sprache, die unter dem .NET-Framework läuft.

    Abseits deiner Frage: Wenn du mit C# auf eine Excel-Datei zugreifen willst, dann musst du das entweder über entsprechende Bibliotheken machen oder du löst das ganze über die sog. COM-Schnittstelle (In deinem Projekt unter Projektexplorer auf "Verweise" rechtsklicke - > "Verweis hinzufügen" -> "COM" -> nach Excel suchen -> Checkbox anhaken -> Auf OK klicken
    Was du nicht vergessen solltest: Wenn du die Anwendung beendest, zerstöre die Excel.Application-Referenz, sonst gurken dir u.U. mehrer unnötige Excel-Instanzen im RAM umher -> Speicherleck.

    Dann nur noch per "using" den nötigen Namespace (Microsoft.Office.Interop.Excel) einbinden und du kannst auf die Excel-Datei zugreifen. Einfach mal Dr. Google nach Excel und C# befragen, findest mit Sicherheit ein paar Beispiele.
    Um jetzt den Code nach C# zu übersetzten könntest du VORERSTE - nicht permanent sondern nur provisorisch - mal den Microsoft.VisualBasic-Namespace importieren (auch wenn ihr mich jetzt verfluchen werde, aber wie gesagt nur provisorisch). Dann kannst du auch die Methoden Weekday() und DateSerial verwenden - musste dich halt drum kümmern, diese Funktionalität selber zu implementieren, wenn du den Namespace wieder entfernst, da er die ein oder andere "Böse Funktion" enthält.

    Wenn du über diese COM-Schnittstelle auf die Zellen zugreifst, dann solltest du einiges beachten!
    - Viele Methoden geben entweder ein Object oder ein Interface zurück - Ich selber verwende da lieber die Klassen (also nicht Excel.Application sondern Excel.ApplicationClass), die sind von den Datentypen her genauer
    - Um mit den Klassen arbeiten zu können, musst du unter Projektexplorer -> Verweise -> Microsoft.Office.Interop.Excel -> Eigenschaften -> Interoptypen einbetten auf 'false' stellen, da du sonst nicht mit den Klassen arbeiten kannst - Compilerfehler
    - Mehr fällt mir jetzt spontan ned ein - werde aber editieren, falls mir noch was einfällt.


    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator

    Erst mal danke für deine ausführlichen Hinweise.
    Um deinen ersten Hinweis zu beantworten ja es handelt sich um VBA und leider darf ich diesen nicht in VB umwandeln sondern soll diesen in C# implementieren, was die ganze Sache ziemlich schwierig macht.

    Zu deinen anderen Hinweisen, die Bibliotheken etc. habe ich schon alle eingebunden und somit stehen mir die Excel Methoden bzw. die Interfaces zur Verfügung.

    Leider bekommt man über Google meist nur die Beispiele von Microsoft und hat nicht eine breite Palette an Beispielen von anderen Fällen etc.

    Bisher habe ich alles über die Interfaces gelöst und wenn ich nun auf die Excel.ApplicationClass übergehe verliere ich überhaupt den Überblick. Außer du hättest ein schönes Beispiel zur Verwendung von Excel.ApplicationClass.

    Ich Google mich weiter durch das Labyrinth und probiere mich langsam vorzutasten..
    Wo du hier Probleme haben wirst ist die Ungenauigkeit von VBA hinsichlich der Datentypen.
    Es wird in deinem Code bspw zu einer Date-Variable ein Integerwert addiert, da aber der + Operator nicht für Date + Integer definiert ist, gibt es hier einen Fehler
    Aber ich werden mich heute evtl noch mal bei dir melden
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator

    ja das mit den Operatoren habe ich schon gemerkt, dass Sie sich etwas unterscheiden.
    Jedoch die Funktion zur KW Woche funktioniert in C#, mir geht es eher expliziter wie die Excel Zelle in C#
    an meine KW Funktion übergeben werden kann um eben abzuprüfen welche KW es ist etc.
    Da in VBA ich einfach mein kalenderwochedin mit Zelle einfach hinschreibe und er automatisch sich errechnet ob alles passt und bei C# meckert er bei Kalenderwoche.
    VBA:

    Quellcode

    1. KalenderwocheNachDin(ws_anfang.Cells(i, 19).value) = KalenderwocheNachDin(Date)


    C# (Keine Überladung für die Kalenderwoche(Kalenderwoche rot unterstrichen) Methode nimmt 1 Argument an):

    Quellcode

    1. (Kalenderwoche(ws_anfang.Cells[i,19].value) = Kalenderwoche(Date) And


    Danke das du dir Zeit nimmst für diesen Excel Spaß..
    Wie gesagt, wenn du COM verwendest, gibt dir vieles ein "Object" zurück, das musst du dann entsprechend casten (implizit wird des in C# eher schwer gehen ;D) Wenn also deine Methode/Funktion einen Integer erwartet, musst du dir erst den Wert aus der Zelle Cells(x,y) in einen Integer casten und kannst ihn dann weiter verwenden.

    Hab hier mal ein kleines Projekt gemacht, das eine Excel-Datei (*.xlsx) öffnet, welches in A1 bis A3 nur Datumswerte enthält und in A1 den String "Text" schreibt. Die Excel-Datei ist in einem Unterordner des Projektes, musste nachher nur noch auf den Desktop kopieren.
    Wenn dir das noch zu wenig ist, dann kann ich dir nur Codeproject empfehlen (Working with Excel Using C#).

    Lg Radinator
    Dateien
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    dani02 schrieb:

    KalenderwocheNachDin
    Das gibt's doch alles im Framework.
    Ist zwar VB.Net, aber das dürfte das kleinste Problem sein.

    Visual Basic-Quellcode

    1. Imports System.Globalization
    2. Public Function CalendarWeek(ByVal Datum As Date) As Short
    3. Dim Cult As New CultureInfo (CultureInfo.CurrentCulture.Name)
    4. Return Cult.Calendar.GetWeekOfYear(Datum,Cult.DateTimeFormat.CalendarWeekRule,Cult.DateTimeFormat.FirstDayOfWeek)
    5. End Function

    Du kannst statt CultureInfo.CurrentCulture.Name natürlich auch andere Kulturen eintragen, falls du in einer Nicht-ISO-Kultur bist.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hallo Leute,

    Danke vielmals für eure schnelle Hilfe!
    Habe mich nochmals in aller Ruhe hingesetzt und Schritt für Schritt übersetzt und siehe da es klappt fast alles, ganz nützlich war hier @petaod Funktion.

    Jetzt habe ich nur noch ein Fehler bzw. Problem in der Zeile wo aus ws.anfang in ws.ziel übertragen werden soll. Ich denke meine Problem war einmal die Funktion zweitens die richtige Klammer Setzung inklusive der Operatoren.

    Nochmals Danke.

    Hier der fast laufende Code (in Kommentar die zu fixende Zeile):

    Quellcode

    1. for (i=13; i <=1044; i++)
    2. {
    3. if (checkDatum(ws_anfang.Cells[i, 19].value2))
    4. {
    5. if ((((CalendarWeek(ws_anfang.Cells[i, 19].value2)) == (Kalenderwoche(DateTime.Now))) & ((ws_anfang.Cells[i, 19].value2)==(datumJahr.Year))) | (((CalendarWeek(ws_anfang.Cells[i, 20].value2)) == (Kalenderwoche(DateTime.Now))) & ((ws_anfang.Cells[i, 20].value2) == (datumJahr.Year))))
    6. {
    7. exApp.DisplayAlerts = false;
    8. ws_anfang.Rows[i].copy ws_ziel.Rows[z]; //ws_ziel.Rows[z] will er noch nicht ...
    9. z = z + 1;
    10. exApp.DisplayAlerts = true;
    11. }
    12. }
    13. }
    @petaod

    Dann funktioniert leider so nicht, er meckert bei ws_ziel : nur aissgnment decrement call ... können als Anweisung verwendet werden.

    Habe nun aber hierzu zumindest eine Lösung gefunden, wo er nicht mehr meckert aber mein Programm nichts tut:

    Quellcode

    1. ws_anfang.Rows[i].copy();
    2. ws_ziel.Rows[z].paste();


    muss noch schauen woran es liegt.