Zeiterfassungstool, Algorithmus zur Auswertung Arbeitszeit.

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von sonne75.

    Zeiterfassungstool, Algorithmus zur Auswertung Arbeitszeit.

    Hallo zusammen,
    ich bin gerade dabei ein Tool in VB Express 2010 zu basteln, dass meine Arbeitszeit auf einen „klick“ auswertet. Basis ist eine Excel Datei. In der Tabelle wird die tägliche Arbeitszeit dem jeweiligen Projekt zugeordnet.Für jedes Projekt gibt es einen Namen und eine Auftragsnummer (Siehe Bild im Anhang).

    Zu meinen Fragen:

    In der Regel gibt es jeden Monat 4-5 Wochen, heißt ich habe 4-5 Arbeitsblätter. Im Moment schaffe ich es nur ein Arbeitsblatt zu öffnen. Wie öffne ich alle Arbeitsblätter auf einmal?

    Gibt es bereits eine fertige Funktion (ähnlich wie in Excel) mit der ich ganz einfach meine Auftragsbezogenen Stunden addiere? Ich möchte am Schluss nur noch eine Ausgabe mit

    Projekt A 0123451 59,75 Stunden
    Projekt B 6543210 32 Stunden

    Andernfalls ist mir noch nicht ganz klar wie ich das hinbekomme. Ansonsten müsste ich für jede Spalte (max 15) in jedem Arbeitsblatt eine Variable anlegen, die Werte zuweisen, und über eine Schleife vergleichenOb die Auftragsnummer dieselbe ist, wenn ja Addiere die Stunden. Es gibt dazu aber eigentlich 3 Werte die gespeichert werden müssen, der Projektname, die Auftragsnummer und die Stundenanzahl. Wie mach ich das?Über ein Mehrdimensionales Array?! Wäre für eine kleine Unterstützung dankbar!
    Bilder
    • bsp_forum.JPG

      60,84 kB, 797×389, 170 mal angesehen
    Am besten machst du es in einem Dictionary(Of String, Integer). String, weil die Auftragsnummer am Anfang eine 0 haben könnte.
    Du öffnest dein Excelblatt, gehst in der Schleife Zeile für Zeile durch und liest die Auftragsnummer ein. Prüfst, ob sie im Dictionary schon existiert, wenn ja, addierst du zum Integerwert die Summe der Wochenstunden dazu, wenn nicht, legst du ein neues Key-Value-Paar an und schreibst den Summenwert rein.
    @sonne75 Wo bleibt da die Dauer? Im Integer?
    @creation Mach Dir zunächst den Unterschied zwischen 1 Uhr und 1 Stunde klar, dann weißt Du, was Du machen musst.
    Nutze die .NET-Strukturen DateTime und TimeSpan. Pass auf beim Konvertieren der Daten von Excel, überzeuge Dich vom Funktionieren Deines Codes :!:
    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!
    danke für die Zahlreichen Antworten!

    Ja es gibt bereits eine Spalte mit der Summe. Ich kann also aus dieser Spalte die jeweilige Auftragsnummer mit dem Projektnamen zuweisen.
    @sonne75
    Du meinst also ein Mehrdim.Array? oder wie finde ich nachher meine Stunden passend zu der Auftragsnummer. Von der Logik ist mir das alles klar, es klemmt nur bei der Umsetzung ins Programm J


    @shaebich
    Ja, es gibt für jede Kalenderwoche ein eigenes Sheet, hier klemmt es auch noch mit dem öffnen, die Workspace(1) bekomme ich hin … aber das zweie Blatt nicht mehr.

    creation schrieb:

    Du meinst also ein Mehrdim.Array?

    Nein, ein Dictionary(Of String, Integer)

    msdn.microsoft.com/de-de/library/xfhwa508(v=vs.110).aspx

    Da sind Key-Value-Paare, jedem Key ist ein Value zugeordnet, es darf keine doppelten Keys geben. Die Typen von Key und Value kann man frei bestimmen. Wie willst du beim Array die Zuordnung machen? Es ist schon viel einfacher so.

    VB.NET-Quellcode

    1. Public dict As New Dictionary(Of String, Integer)
    2. ....
    3. dict.Add("1234", 59) 'fügt eine neue Projektnummer und Stundenanzahl hinzu
    4. If dict.ContainsKey("1234") 'prüft, ob 1234 schon da ist
    5. dict("1234") + = 65 'addiert 65 zu 59, die schon drin ist, dazu
    Guten Abend,


    ich teste gerade die Vorgeschlagene Vorgehensweise. Ich Nun zu den Details, ich habe nun die Tabelle vor mir.
    In jeder Arbeitsmappe steht die Auftragsnummer in den Zeilen B16:B34 und die Summe, also die Quersumme des Auftrags, dann in J16:J34.

    Folgendes versuche ich:

    VB.NET-Quellcode

    1. dict.Add(objSheet.Range("J17").Value, objSheet.Range("B17").Value)
    2. If dict.ContainsKey("J17") Then 'Also die gleiche Auftragsnummer
    3. dict("J17") += Wie verweise ich auf den aktuellen Treffer? This?
    4. End If


    Ich wollte dein Beispiel überprüfen und mir den Wert in einem Label anzeigen lassen, hier geht aber wohl was schief

    Label6.Text &= dict. <- wie greife ich auf Schlüssel zu?


    Oder bin ich auf einem ganz falschen Weg?
    Mach bitte Option Strict On!! Du hast schon mal die Auftragsnummer und die Summe verwechselt, bei dict.Add, das wäre dir sonst nicht passiert, weil das Eine ist String, das andere ist Integer.

    Und überhaupt, die Logik fehlt in deinem Code völlig ;(

    Ansonsten, hol dir erstmal die Werte:

    VB.NET-Quellcode

    1. Dim Auftragsnummer As String = objSheet.Range("B17").Value.ToString
    2. Dim Stunden As Integer=CInt(objSheet.Range("J17").Value)
    3. If dict.ContainsKey(Auftragsnummer) Then 'was hat deine Auftragsnummer mit "J17" zu tun?!?
    4. dict(Auftragsnummer) + = Stunden
    5. Else
    6. dict.Add(Auftragsnummer, Stunden)
    7. End If
    Hallo,

    sonne75 schrieb:

    Mach bitte Option Strict On!! Du hast schon mal die Auftragsnummer und die Summe verwechselt, bei dict.Add, das wäre dir sonst nicht passiert, weil das Eine ist String, das andere ist Integer.
    [/vbnet]


    danke für den Hinweis, du hast natürlich Recht, man sollte sich vorher überlegen was man tippt, ich habe es auch bemerkt.

    Mit dem Datentyp ist mir schon aufgefallen, das hatte ich schon geändert.
    Eine Frage bleibt aber noch, sorry für meine Frage aber ich möchte es verstehen, nicht nur abtippen!!

    In deinem Beispiel:

    Dim Auftragsnummer As String = objSheet.Range("B17").Value
    Dim Stunden As Double = CDbl(objSheet.Range("J17").Value)

    Lege ich die Variable Auftragsnummer als String und die Stunden als Double an, ich weiße die Werte der Zeile B17 bzw. J17 zu.
    Wenn ich auf alle Werte zwischen B17:B34, J17:J34 zugreifen möchte, würde ich mit einer Schleife bei 17 beginnen und bis 34 Zählen.
    Aber, dann hat meine Variable ja die Werte J17:J34.

    Ich hab das so verstanden. Mit dict.Contains Key wird ein, um es sich besser vorstellen zu können, String und Integer „Topf“ angelegt?
    Alles was dann zB. Die gleiche Nummer ist wird auf die Anzahl der Stunden addiert?

    Funktioniert aber irgendwie nicht, vielleicht steh ich auch auf dem Schlauch, Sorry für meine nervige Fragerei, aber ich möchte es gerne verstehen und
    Ich bin der Meinung, es klappt so nicht richtig.

    Ich habe nochmals die Tabelle angehängt..

    A
    B
    C
    D
    E
    F
    G
    H
    I
    J

    Auftrag
    Auftragnr.
    Mo
    Di
    Mi
    Do
    Fr
    Sa
    So
    Summe
    A
    12345678
    2

    1




    3
    B
    654321
    8


    4



    12
    C
    77886655




    8


    8
    A
    12345678


    5
    2




    7










    Du hast den Code von mir falsch zitiert und ein .ToString vergessen ;(

    creation schrieb:

    Mit dict.Contains Key wird ein, um es sich besser vorstellen zu können, String und Integer „Topf“ angelegt?

    Bist du des Englischen mächtig? "ContainsKey" bedeutet "enthält Schlüssel?". Es ist eine Frage, ob dieser Schlüssel schon vorhanden ist (also schon mal angelegt wurde, weil eine Zeile mit derselben Auftragsnummer ausgelesen wurde). Dann wird zum vorhandenen Inhalt der Inhalt der aktuellen Zeile addiert.
    Ich glaube das Problem ist, dass du ein Stück weiter bist als ich. ContainsKey ist mir soweit klar. Mit der Abfrage beschränke ich mich auf die eine Zeile.
    Bedeutet aber, ich muss entweder für alle Zeilen von J17 bis J34 eine Abfrae anlegen bzw. 17 Variablen anlegen, oder wie hole ich mir am "einfachsten" alle Werte aus der Tabelle.

    ich bin raus ;D schönen Sonntag noch ^^
    Hallo,

    habe mich länger mit dem Thema nicht mehr befasst, da ich geschäftlich unterwegs war, deshalb die „späte“ Antwort. Ich habe es mir nochmals durch den Kopfgehen lassen, auch auf
    die Gefahr, dass der Eindruck entsteht ich bin komplett Beratungsresistent, möchte ich nochmals bemerken, dass ich noch immer nicht ganz klar bin. Aber nochmals von vorne, wie ich es verstehe.

    Mit

    VB.NET-Quellcode

    1. dict.Add(objSheet.Range("J17").Value, objSheet.Range("B17").Value)


    Füge ich meine meine Summer der Stunden als auch die Auftragsnummer/ Projektnamen hinzu.

    Hier möchte ich ein dict.Add von „J14 bis J24“ gleiches gilt für den Wertebereich „B“.
    Am einfachsten könnte ich es so machen:

    VB.NET-Quellcode

    1. dict.Add(objSheet.Range("J17").Value, objSheet.Range("B17").Value)
    2. dict.Add(objSheet.Range("J18").Value, objSheet.Range("B18").Value)
    3. dict.Add(objSheet.Range("J19").Value, objSheet.Range("B19").Value)
    4. dict.Add(objSheet.Range("J20").Value, objSheet.Range("B20").Value)


    Jedoch ist diese Variante nicht dier schnellste, daher am besten über eine Schleife bis 34 zählen. .> OK!?

    Wenn ich es so mache:

    VB.NET-Quellcode

    1. Dim Auftragsnummer As String = objSheet.Range("B17").Value.ToString
    2. Dim Stunden As Integer=CInt(objSheet.Range("J17").Value)


    Muss ich ja für jeden Wertebereich eine eigene Variable anlegen.

    Was mir nun fehlt, ist mit ContainsKey zu prüfen ob es die aktuelle Auftragsnummer schon gibt und WENN JA Addiere es auf die gefundenen Stunden.

    So ist schwachsinn:

    VB.NET-Quellcode

    1. If dict.ContainsKey(objSheet.Range("B21").Value) Then
    2. dict(Auftragsnummer) += Stunden
    3. Else
    4. dict.Add(Auftragsnummer, Stunden)
    5. End If
    6. If dict.ContainsKey(objSheet.Range("B22").Value) Then
    7. dict(Auftragsnummer) += Stunden
    8. Else
    9. dict.Add(Auftragsnummer, Stunden)
    10. End If


    Ich weiß nicht mit wieviel Schleifen, Variablen is es versucht habe, bekomme es aber irgendwie nicht hin. Entwerder meckert VB bezüglich Datenkonflikt, oder ich bekomme eine Ausgabe die nicht stimmt.
    Von daher wäre ich für eine weiter Unterstüzung dankbar, glaubt mir ich will nicht einfach den „Code“ abschreiben, ich habe mittlerweile einige Stunden in das Projekt investiert aber wenn man nicht weiter kommt,
    auch wenn es noch so „logisch“ ist, ist das echt deprimierend.

    Daher bitte ich um eine Letzte Hilfe J

    creation schrieb:

    So ist schwachsinn:


    Warum ist es Schwachsinn?

    Ich habe dich doch gefragt:

    sonne75 schrieb:

    Überleg dir doch, wie du J17 bis J34 in einer Schleife einlesen kannst... "J17" ist nur ein String in dem Fall und 17-34 sind nur Zahlen...


    Wenn du eine Schleife machst:

    VB.NET-Quellcode

    1. For i=12 To 24
    2. If dict.ContainsKey(objSheet.Range("B" & i.ToString).Value) Then
    3. ....'Hier dein Rest
    4. End If
    5. Next


    dann hast du doch schon die Lösung...