1. Liebe Forumsgemeinde,

    aufgrund der Bestimmungen, die sich aus der DSGVO ergeben, müssten umfangreiche Anpassungen am Forum vorgenommen werden, die sich für uns nicht wirtschaftlich abbilden lassen. Daher haben wir uns entschlossen, das Forum in seiner aktuellen Form zu archivieren und online bereit zu stellen, jedoch keine Neuanmeldungen oder neuen Kommentare mehr zuzulassen. So ist sichergestellt, dass das gesammelte Wissen nicht verloren geht, und wir die Seite dennoch DSGVO-konform zur Verfügung stellen können.
    Dies wird in den nächsten Tagen umgesetzt.

    Ich danke allen, die sich in den letzten Jahren für Hilfesuchende und auch für das Forum selbst engagiert haben. Ich bin weiterhin für euch erreichbar unter tti(bei)pcwelt.de.
    Dismiss Notice

Excel Datum aus KW & Feldfarbe verändern durch Zahleneingabe

Discussion in 'Office-Programme' started by d4chillin, Jun 5, 2008.

Thread Status:
Not open for further replies.
  1. d4chillin

    d4chillin Byte

    Hallo,

    ich hab 2 Fragen:

    1. Ich habe den Wochentag und die KW, kann ich mir daraus in Excel das datum des Tages anzeigen lassen ?

    2. In einem Feld steht ein Text. Durch Zahleneingabe in dem Feld daneben möchte ich die Textfarbe(zur not auch Hintergrundfarbe) des Feldes mit Text verändern ?


    Jemand eine Idee ? ich wär euch sehr dankbar!!!!!

    Grüße

    d4chillin
     
  2. Beverly

    Beverly Halbes Megabyte

    Hi,

    das 2. Problem kannst du mit Bedingter Formatierung lösen. Angenommen A1 soll in Abhängigkeit von B1 gefärbt werden: wähle unter Bedingung1 "Formel ist" aus und gib als Formel ein =B1=10 (wenn bei einem Wert von 10 gefärbt werden soll) und wähle dann unter Format das gewünschte Format aus.
     
  3. Hascheff

    Hascheff Moderator

    Hallo,

    zu 2.: wie bunt soll denn die Spalte werden und welche Excel-Version hast du?

    zu 1.: Oh, das ist ja mal eine ganz neue Frage! Interessant!
    @ Beverly: Tüftelst du schon? Wenn nicht, lass mich machen!
     
  4. Beverly

    Beverly Halbes Megabyte

    @Hascheff,

    Frage 1 überlasse ich dir gern. Bin nicht so der Formelspezialist.
     
  5. Hascheff

    Hascheff Moderator

    Wie erwartet war die Lösung knifflig. Eine Schwierigkeit besteht darin, dass für die Funktionen KALENDERWOCHE und WOCHENTAG verschiedene Typen durch den zweiten Parameter möglich sind. (Woche beginnt Sonntag oder Montag, bei WOCHENTAG kann Montag außerdem 0 oder 1 sein.) Ich habe deshalb einen Korrekturfaktor eingebaut, der vom Anwender auch direkt in die Formel eingetragen werden kann.

    Es gibt noch ein Problem mit dem Wochentag. Ich habe vergessen, den TO zu fragen, in welcher Form der Wochentag vorliegt. Da gibt es viele Möglichkeiten:
    - Es handelt sich um ein Datum, welches als "TTT" oder "TTTT" formatiert wurde. (-> "Sa" oder "Samstag") In dem Fall ist keine Funktion nötig, man muss nur die Zelle anders formatieren.
    - der Wochentag wird als Wort (Mo, Di, ... So oder Montag, Dienstag ... Sonntag) angegeben. Dies ist die wahrscheinlichste Variante. Ich habe diese Variante aber noch nicht berücksichtigt, ich komme später noch mal darauf zurück.
    - Der Wochentag wird als Zahl dargestellt. Dafür gibt es, wie oben dargestellt, drei Varianten. Meine Formel geht von diesem Fall aus.

    Meine Formel wurde in Excel 2000 entwickelt. Prüft bitte, ob Eure Excel-Version die Funktionen KALENDERWOCHE und WOCHENTAG auch so behandelt. Für WOCHENTAG ist der Typ-Parameter optional, Standard ist 1.

    Ich habe schon daran gedacht, die Formel als benutzerdefinierte Funktion einzustellen, erst recht, wenn der Wochentag als Wort angegeben ist, dann würde ich die Umwandlung des Wortes in eine Zahl als eigenständige Funktion darstellen.
    Bevor ich mich daran mache, wollte ich aber erst mal zeigen, dass es vorangeht.
    @ Beverly: In der benutzerdefinierten Funktion bietet es sich an, einige Parameter optional zu stellen. Ich habe das aber noch nie probiert. Geht das bei benutzerdefinierten Funktionen überhaupt, wenn ja, wie?

    Ich hänge die Excel-Datei an, mit der ich die Formel erstellt habe. Damit lässt sich manches besser verstehen, was ich im folgenden darstelle. In B7 und vielleicht auch anderswo erkennt man, dass ursprünglich mehrere Testspalten vorhanden waren.

    Die Parameter der Formel sind:
    B2: Kalenderwoche
    B3: Wochentag
    B4: Jahr
    B6: Typ von WOCHENTAG
    B7: Korrektur in Abhängigkeit vom Typ

    Weiterhin enthält die Tabelle:
    B5: Typ von KALENDERWOCHE

    Die Korrektur hat folgende Größe:
    Für Typ 1 (So=1 ... Sa=7) von KALENDERWOCHE:
    WOCHENTAG ist Typ 1 (So=1 ... Sa=7): 1
    WOCHENTAG ist Typ 2 (Mo=1 ... So=7): =WENN(B3=7;2;1)
    WOCHENTAG ist Typ 3 (Mo=0 ... So=6): =WENN(B3=6;2;1)

    Für Typ 2 (Mo=1 ... So=7) von KALENDERWOCHE:
    WOCHENTAG ist Typ 1 (So=1 ... Sa=7): =WENN(B3=1;0;1)
    WOCHENTAG ist Typ 2 (Mo=1 ... So=7): 1
    WOCHENTAG ist Typ 3 (Mo=0 ... So=6): 1

    Zusammengefasst: Korrektur 1 ist Standard, das liegt daran, dass in der ersten Woche null Wochen vergangen sind. Es ist unwahrscheinlich, dass in einer Tabelle verschiedene Zählweisen für den Beginn von KALENDERWOCHE und WOCHENTAG realisiert sind, aber wenn: Da je nach Variante Sonntag oder Montag dann in verschiedenen Wochen liegen, muss sieben Tage vor oder zurück gezählt werden.
    Dass in der Formel unten Typ 2 und 3 von WOCHENTAG nicht unterschieden werden müssen, liegt daran, dass sich der Unterschied gleichermaßen auf den 1.1. und das gesuchte Datum auswirkt.

    Nun steht in B17 die Formel:
    Code:
    =DATWERT("1.1."&B4)+7*(B2-B7)-WOCHENTAG(DATWERT("1.1."&B4);B6)+B3
     

    Attached Files:

  6. Beverly

    Beverly Halbes Megabyte

    Hi Hascheff,

    vom Prinzip her kann man sicher auch spezifische Parameter einbinden, denn eine benutzerdefinierte Funktion ist ja auch VBA-Code. Aber mir ist nicht so ganz klar, welche Parameter du meinst. Deine Datei kann ich leider nicht herunterladen, bzw. es wird Dateifehler beim Öffnen/Extrahieren angezeigt.
     
  7. Hascheff

    Hascheff Moderator

    :( Eine normale Excel2000-Datei, mit Winrar gepackt. Ich versuch es mal ohne Packen. Ich hänge einfach .txt an.

    Normale Parameter der Funktion sind Kalenderwoche und Wochentag. Das Jahr ist natürlich auch noch wichtig, aber wenn kein Jahr angegeben wird, kann man das aktuelle Jahr annehmen.
    Ebenso ist es mit der Zählweise der Wochentage. Es macht einen kleinen Unterschied, ob die Funktion KALENDERWOCHE, mit der die Zahl erzeugt wurde, die Parameter der Funktion ist, die Wochenzählung am Sonntag oder am Montag beginnt.
    Es muss auch angegeben werden, ob die Zahl 1 für den Wochentag Sonntag oder Montag bedeutet.
    Man kann als Standard annehmen, dass die Woche in beiden Fällen am gleichen Tag beginnt. Wenn aber jemand anders zählen will oder muss, kann er das angeben.
     

    Attached Files:

  8. Beverly

    Beverly Halbes Megabyte

    Hi Hascheff,

    ach so, diese Parameter meinst du, klar. Auf welche Weise sollen sie denn übergeben werden - direkt als Konstanten in der Funktion festschreiben, sodass sie im Code ausgetauscht werden müssen oder sollen sie aus verschiedenen Zellen im Tabellenblatt entnommen werden?

    Die Datei konnte ich nicht lesen, weil ich nur das in WIN integrierte Zip-Programm besitze und offensichtlich hat es Probleme mit diesem Zip-Format.
     
  9. Beverly

    Beverly Halbes Megabyte

    Hi Hascheff,

    ich bin mal jetzt davon ausgegangen, dass die Ausgangswerte in den selben Zellen stehen wie in deinem Beispiel

    Code:
    Private Function kwdatum()
        kwdatum = DateValue("1.1." & Range("B4")) + 7 * (Range("B2") - Range("B7")) - Weekday(DateValue("1.1." & Range("B4")), Range("B6")) + Range("B3")
    End Function
    
    Das Problem dabei ist, dass die Zelle im Anschluss erst noch als Datum formatiert werden muss, genau wie bei deiner Formel. Man könnte mit der Formel ja noch das Format anpassen

    =TEXT(DATWERT("1.1."&B4)+7*(B2-B7)-WOCHENTAG(DATWERT("1.1."&B4);B6)+B3;"TT.MM.JJJJ")

    was mit VBA dann so aussehen würde
    Code:
    Private Function kwdatum()
        kwdatum = Application.Text(DateValue("1.1." & Range("B4")) + 7 * (Range("B2") - Range("B7")) - Weekday(DateValue("1.1." & Range("B4")), Range("B6")) + Range("B3"), "dd.mm.yyyy")
    End Function
    
    Das Problem ist aber, dass ich mir nicht sicher bin, wie sich das auf irgendwelche weiteren Berechnungen auswirkt, da die Zelle auf diese Weise ja als Text formatiert ist.
     
  10. Hascheff

    Hascheff Moderator

    Hi Beverly,
    es gibt Programmiersprachen, da kann man in den Code einer Funktion auch Befehle unterbringen, die nichts mit der Berechnung des Funktionswertes zu tun haben. VBA gehört offensichtlich nicht dazu. Ich habe den im Code unten auskommentierten Befehl probiert, er ist wirkungslos, genauso wie "as Date" im Kopf der Funktion.

    Die Sache mit den Parametern stelle ich mir so vor, wobei die Sache mit der Korrektur provisorisch ist:
    Code:
    Function kwdatum(KW, WT, Jahr, WTTyp As Variant) As Date
        Dim Korrektur As Integer
        'Selection.NumberFormat = "d/m/yyyy"
        Korrektur = 1
        If Not IsNumeric(Jahr) Then Jahr = Year(Now())
        kwdatum = DateValue("1.1." & Jahr) + 7 * (KW - Korrektur) - Weekday(DateValue("1.1." & Jahr), WTTyp) + WT
    End Function
    
    
    Mit der Zeile " If Not IsNumeric(Jahr) Then Jahr = Year(Now())" habe ich auch erreicht, dass kein Jahr angegeben werden muss. Man erkennt nur im Formelassistenten nicht, dass der Parameter optional ist.
     
  11. Beverly

    Beverly Halbes Megabyte

    Hi Hascheff,

    Konstanten kann man nicht in einer Funktion übergeben, soweit ich weiß, aber man kann sie außerhalb der Prozedur deklarieren:

    Code:
    Option Explicit
    Const Korrektur As Integer = 1
    
    Function kwdatum(KW, WT, Jahr, WTTyp As Variant)
        Application.Volatile
        If Not IsNumeric(Jahr) Then Jahr = Year(Now())
        kwdatum = DateValue("1.1." & Jahr) + 7 * (KW - Korrektur) - Weekday(DateValue("1.1." & Jahr), WTTyp) + WT
    End Function
    
    Ich habe noch Application.Volatile ergänzt, sodass eine Neuberechnung automatisch erfolgt.

    Damit die Zelle als Datum formatiert wird, hatte ich schon Application.Caller vewendet, funktioniert jedoch auch nicht, weil eine Schleife zur Neuberechnung aller Zellen, die die Funktion enthalten, ausgelöst würde - und das unterbindet Excel. Aber es funktionert, wenn man zusätzlich noch das Worksheet_Change Ereignis verwendet:

    Code:
    Private Sub Worksheet_Change(ByVal Target As Range)
        Dim raZelle As Range
        If Target.Count > 1 Then
            For Each raZelle In Selection
                If InStr(raZelle.Formula, "=kwdatum(") > 0 Then raZelle.NumberFormat = "dd/mm/yyyy;   "
            Next raZelle
        Else
            If InStr(Target.Formula, "=kwdatum(") > 0 Then Target.NumberFormat = "dd/mm/yyyy;  @"
        End If
    End Sub
    
     
  12. Hascheff

    Hascheff Moderator

    Hi Beverly,
    Konstanten sind nur in umfangreichen Modulen sinnvoll. Hier ist Korrektur nur vorläufig Konstante, bis der Code an der Stelle weiterentwickelt wird.

    Vorher gibt es aber noch was wichtigeres. Wie ich in #5 im zweiten Abschnitt schrieb, ist es am wahrscheinlichsten, (wenn jemand die Frage stellt,) dass der Wochentag erst mal als Wort dargestellt ist.

    Mein erster Versuch sieht so aus:
    Code:
    Function WOCHENTAG2ZAHL(WT_Wort As Variant) As Integer
    If IsNumeric(WT_Wort) Then
            WOCHENTAG2ZAHL = Weekday(WT_Wort)
        Else
            Select Case WT_Wort
                Case "So", "Sonntag":    WOCHENTAG2ZAHL = 1
                Case "Mo", "Montag":     WOCHENTAG2ZAHL = 2
                Case "Di", "Dienstag":   WOCHENTAG2ZAHL = 3
                Case "Mi", "Mittwoch":   WOCHENTAG2ZAHL = 4
                Case "Do", "Donnerstag": WOCHENTAG2ZAHL = 5
                Case "Fr", "Freitag":    WOCHENTAG2ZAHL = 6
                Case "Sa", "Samstag":    WOCHENTAG2ZAHL = 7
                End Select
        End If
    End Function
    
    Mir ist rätselhaft, warum der Code bei der Anwendung auf eine leere Zelle den Wert 7 liefert.

    BTW: Der TO war seit Eröffnung des Threads nicht mehr im Forum.
     
  13. Beverly

    Beverly Halbes Megabyte

    Da muss ich dir widersprechen, denn der Vorteil der Deklaration als Konstante zu Beginn jeglichen Codes macht es wesentlich einfacher, die Konstante bei Erfordernis zu ändern und dadurch wird der Code wesentlich übersichtlicher, gleichgütltig wie lang oder kurz er ist. Außerdem kann eine Kontante sowieso im Code nicht verändert werden, weshalb eine Deklaration innerhalb des Codes wenig sinnvoll ist.

    Ob sich jemand die Mühe macht, den Wochentag als Wort in die Funktion einzugeben statt als Zahl, soll dahingestellt bleiben, da ja die Gschmäcker bekanntlich verschieden sind :). Aber auf jeden Fall sollte bei Eingabe als Zahl geprüft werden, ob sie innerhalb des gültigen Bereichs liegt, also zwischen 1 und 7.

    Code:
    Function WOCHENTAG2ZAHL(WT_Wort As Variant) As Integer
        If IsNumeric(WT_Wort) And WT_Wort > 0 And WT_Wort < 8 Then
            WOCHENTAG2ZAHL = Weekday(WT_Wort)
        Else
            Select Case WT_Wort
                Case "So", "Sonntag":    WOCHENTAG2ZAHL = 1
                Case "Mo", "Montag":     WOCHENTAG2ZAHL = 2
                Case "Di", "Dienstag":   WOCHENTAG2ZAHL = 3
                Case "Mi", "Mittwoch":   WOCHENTAG2ZAHL = 4
                Case "Do", "Donnerstag": WOCHENTAG2ZAHL = 5
                Case "Fr", "Freitag":    WOCHENTAG2ZAHL = 6
                Case "Sa", "Samstag":    WOCHENTAG2ZAHL = 7
            End Select
        End If
    End Function
    
    Da weiß ich jetzt leider nicht, was genau du damit meinst.
     
  14. Urs2

    Urs2 Megabyte

    Wenn man "Case Select" keine gültige Auswahlmöglichkeit anbietet, soll es manchmal erratisch reagieren.
    Je nach Wetter? Es wird hier offensichtlich die letzte Case-Zeile gewählt...
    Bei mir (mit Excel 2003 und schönem Wetter) ergibt eine leere Zelle wie gewünscht gar keinen Wert.

    Versuche es einmal so >

    Case "Sa", "Samstag": WOCHENTAG2ZAHL = 7
    Case Else: WOCHENTAG2ZAHL = "" >oder> Exit Function

    End Select


    Gruss Urs
     
  15. Beverly

    Beverly Halbes Megabyte

    Hi,

    ich verstehe immer noch nicht, was ihr mit "leere Zelle" meint - Funktion ohne Wertangabe in Klammern bzw. nicht im Code definierten Wert oder noch etwas ganz anderes?

    Bei einer leeren Funktion wird doch logischerweise #WERT ausgegeben und wenn der Wert in Klammern nicht in der Funktion definiert ist eine Null - auch ohne Case Else. Ich verwende Excel2002.
     
  16. Urs2

    Urs2 Megabyte

    Normalerweise schon, aber das Case Select verfolgt seine eigenen, unerfindlichen Gedankengänge...
    ...wie offensichtlich bei Hascheff...
    ...und #WERT könnte unbedarfte Leute schon erschrecken...

    Ich hatte zuerst bei "" eine freundlichere Fehlermeldung drin, aber die Zelle ist wohl zu klein...
    Case Else: Exit Function
    müsste eigentlichl das Problem umgehen, oder nicht?

    Warten auf Hascheff...

    Gruss Urs
     
  17. Beverly

    Beverly Halbes Megabyte

    Hi Urs,

    bei mir bewirkt diese Codezeile überhaupt nichts, da die Funktion gar nicht ausgeführt wird, wenn kein Wert in die Klammern geschrieben wird. Folglich wird automatisch #WERT ausgegeben.
     
  18. Hascheff

    Hascheff Moderator

    Hallo ihr beiden,
    bevor ich weiter experimentiert habe, habe ich erst mal ein Screenshot für Beverly erstellt.
    $WT7.gif
    "Case Else" hatte ich auch schon mal im Code, auch heute noch mal probiert, es hat nichts genützt. Dann kam mir die Erkenntnis: IsNumeric nimmt die leere Zelle als numerisch, behandelt sie wie 0 und die hat, wie der Screenshot zeigt, den Funktionswert 7.
    Also muss der Code so sein:
    Code:
    Function WOCHENTAG2ZAHL(WT_Wort As Variant) As Variant
    Application.Volatile
    If IsNumeric(WT_Wort) Then
            If WT_Wort = "" Then
                    WOCHENTAG2ZAHL = ""
                Else
                    WOCHENTAG2ZAHL = Weekday(WT_Wort)
                End If
        Else
            Select Case WT_Wort
                Case "So", "Sonntag":    WOCHENTAG2ZAHL = 1
                Case "Mo", "Montag":     WOCHENTAG2ZAHL = 2
                Case "Di", "Dienstag":   WOCHENTAG2ZAHL = 3
                Case "Mi", "Mittwoch":   WOCHENTAG2ZAHL = 4
                Case "Do", "Donnerstag": WOCHENTAG2ZAHL = 5
                Case "Fr", "Freitag":    WOCHENTAG2ZAHL = 6
                Case "Sa", "Samstag":    WOCHENTAG2ZAHL = 7
                Case Else: WOCHENTAG2ZAHL = "#WERT"
                End Select
        End If
    End Function
    
    Application.Volatile hat mir gefallen, das hab ich hier auch eingebaut.
    Den Funktionstyp habe ich in Variant gewandelt, damit keine Fehlermeldung bei "" kommt. Andererseits musste ich in "Case Else" die Fehlermeldung simulieren. Wie macht man das eigentlich echt?

    Zum Schluss noch ein Schnappschuss.
    $WTSonnabend.gif

    Mir fällt noch was ein:
    [Mo, Di, ... So] und auch [Montag ...] habe ich in den benutzerdefinierten Listen. Kann man das im Code nutzen?
     
  19. Urs2

    Urs2 Megabyte

    @Hascheff

    Ich hatte leider nicht die ganze Function getestet, nur das Select Case, weil ich wusste, dass das manchmal Aerger macht...
    Aber jetzt ist alles klar.

    Ich würde >

    - die "unvernünftigen" Zahlen abfangen, er rechnet auch mit -1 oder 9 >>> sinnlos, aber das Resultat sieht aus wie echt...

    - Die Fehler explizit anzeigen, es muss ja nicht kryptisch sein, wie bei MS
    > Gross-/Kleinschreibung muss beachtet werden
    > "Donnerstag" und ""Domerstag" sehen gleich aus, und ein Leerzeichen hinten dran sieht man nicht... ein Tipp ist willkommen...

    Code:
    Function WOCHENTAG2ZAHL(WT_Wort As Variant) As Variant
    Application.Volatile
    
        If IsNumeric(WT_Wort) Then
            If WT_Wort = "" Then
                WOCHENTAG2ZAHL = ""
                    'er würde auch mit grösseren Zahlen sinnlos rechnen...
            ElseIf WT_Wort < 1 Or WT_Wort > 7 Then
                WOCHENTAG2ZAHL = "Zahl 1-7 !"
                    'warum nicht einfach >>>   = WT_Wort ??
            Else: WOCHENTAG2ZAHL = Weekday(WT_Wort)
            End If
        Else
            Select Case WT_Wort
                Case "So", "Sonntag":    WOCHENTAG2ZAHL = 1
                Case "Mo", "Montag":     WOCHENTAG2ZAHL = 2
                Case "Di", "Dienstag":   WOCHENTAG2ZAHL = 3
                Case "Mi", "Mittwoch":   WOCHENTAG2ZAHL = 4
                Case "Do", "Donnerstag": WOCHENTAG2ZAHL = 5
                Case "Fr", "Freitag":    WOCHENTAG2ZAHL = 6
                Case "Sa", "Samstag":    WOCHENTAG2ZAHL = 7
                Case Else: WOCHENTAG2ZAHL = "Text ??"
            End Select
        End If
    End Function
    
    Benutzerdefinierte Liste im Code benutzen? Weiss ich nicht, aber ich denke nicht, dass das vorgesehen ist....
    Der Code wäre dann ja an diesen PC gebunden, also doch besser hart codieren.

    Gruss Urs
     
  20. Beverly

    Beverly Halbes Megabyte

    @Hascheff,

    aha, du nimmst also den Wert aus einer Zelle, das war nicht so granz klar. Man kann ja schließlich auch den Wert direkt in die Funktion schreiben, was ich gemacht hatte, und da trat dieses Problem nicht auf.

    Wozu genau willst du denn die benutzerdefinierten Listen verwenden?


    @Urs,

    das hatte ich in meinen Code schon integriert.

    Weshalb so kompliziert? Das sollte es doch auch tun

    Code:
    Function WOCHENTAG2ZAHL(WT_Wort As Variant) As Variant
        Application.Volatile
        If IsEmpty(WT_Wort) Or IsNumeric(WT_Wort) Then
            If WT_Wort > 0 And WT_Wort < 8 Then
                WOCHENTAG2ZAHL = Weekday(WT_Wort)
            Else
                WOCHENTAG2ZAHL = ""
            End If
        Else
            Select Case WT_Wort
                Case "So", "Sonntag":    WOCHENTAG2ZAHL = 1
                Case "Mo", "Montag":     WOCHENTAG2ZAHL = 2
                Case "Di", "Dienstag":   WOCHENTAG2ZAHL = 3
                Case "Mi", "Mittwoch":   WOCHENTAG2ZAHL = 4
                Case "Do", "Donnerstag": WOCHENTAG2ZAHL = 5
                Case "Fr", "Freitag":    WOCHENTAG2ZAHL = 6
                Case "Sa", "Samstag":    WOCHENTAG2ZAHL = 7
                Case Else: WOCHENTAG2ZAHL = ""
            End Select
        End If
    End Function
    
     
Thread Status:
Not open for further replies.

Share This Page