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] WENN-Abfrage, 3 Bedingungen

Discussion in 'Office-Programme' started by Tiffiklotz, Sep 18, 2009.

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

    Tiffiklotz Byte

    Kann man eine WENN-Abfrage mit 3 Bedingungen erstellen, wenn ja wie?

    Ich möchte folgendes "programmieren":
    Eine einfache WENN-Abfrage kriege ich hin, auch eine WENN(UND)-Abfrage ist nicht das Problem, aber wie kann ich die drei Bedingungen für b verknüpfen?
    Würde mich sehr über eure Hilfe freuen!
    :rolleyes:

    ___________________________________________

    EDIT: habs durch Probieren herausgefunden, dennoch danke!

    Lösung:

    =WENN(E3<=17,5;0,75;(WENN(UND(E3>17,5;E3<=25);0,9;(WENN(E3>25;1)))))

    (E3 ist das Eingabefeld f&#252;r d)
     
    Last edited: Sep 18, 2009
  2. Hascheff

    Hascheff Moderator

    Bitte, gern.

    Aber, da ist noch ein Fehler. Jetzt hab ich keine Zeit, ich komm noch mal wieder.
    Gruß
    Hascheff
     
  3. Hascheff

    Hascheff Moderator

    Hallo Tiffiklotz,
    direkt falsch ist deine Formel nicht, aber es kann etwas weggelassen werden.

    =WENN(E3<=17,5;0,75;(WENN(E3<=25;0,9;1)))

    Das erste WENN prüft E3<=17,5. Danach muss das im Sonst-Zweig nicht mehr geprüft werden, das UND ist deshalb überflüssig. Aus dem gleichen Grund kann das letzte WENN gelöscht werden.

    Gruß
    Hascheff
     
  4. Tiffiklotz

    Tiffiklotz Byte

    Das gleiche würde ich gerne in VBA programmieren.

    Habe es bisher so versucht:

    Aber dort erscheint folgender Fehler: "End If ohne If-Block"
     
  5. VB-Coder

    VB-Coder Megabyte

    Versuchs mal so
    oder so
     
  6. Tiffiklotz

    Tiffiklotz Byte

    Also bisher funktioniert mein Programm als Ganzes noch nicht, aber ich bastel weiter. Habe auch noch etwas Zeit ...
    Diese If Abfrage habe ich nun komplett ohne EndIf gemacht:

    So kommt momentan keine Fehlermeldung.

    Allerdings kommt nun ein anderer Fehler, den ich nicht nachvollziehen kann:

    In einer Textbox soll die Knicklänge, die zuvor berechnet wurde, ausgegeben werden.

    Berechnung:
    LichteGeschosshöhe ist eine Variable, die zu Beginn des Programms vom User eingegeben wird

    Ausgabe:
    Eigentlich funktioniert die Ausgabe so, so habe ich es in der Vorlesung gelernt und mehrfach erfolgreich benutzt. Aber hier klappts nicht!:confused:
     
  7. Urs2

    Urs2 Megabyte

    Hallo Tiffiklotz,

    1. If-Zeile <> If-Block
    - für einfache If-Abfragen (wie Deine Abfragen) reicht eine If-Zeile >>> diese erhält nie ein EndIf.
    - komplexere Abfragen brauchen einen If-Block >>> der muss immer eine Zeile mit EndIf haben.

    Deine 3 Ifs schliessen sich ja gegenseitig aus, also kannst Du sie in einen If-Block verpacken.
    Bei der 1. Uebereinstimmung verlässt das Makro dann den If-Block, ohne weiter sinnlos zu prüfen... Also so >
    Code:
    If Wanddicke <= 175 Then
        Knicklängenbeiwert = 0.75
    ElseIf Wanddicke <= 250 Then
        Knicklängenbeiwert = 0.9
    Else
        Knicklängenbeiwert = 1
    End If

    2. Ausgabe der Knicklänge
    Dein Sub weist der Variablen (die Du vorher berechnet hattest...) den Wert zu, den Du in diese Textbox eingibst........:confused:

    Du hast eine Textbox in der Du die LichteGeschossHöhe eingibst. Richtig ?
    Und eine Textbox in die die Wandstärke eingegeben wird. Richtig ?
    Dann berechnet der Code zuerst den Knicklängenbeiwert und dann die Knicklänge. Richtig ?

    Dann nimm für die Ausgabe keine Textbox, sondern ein Bezeichnungsfeld (Label).
    Dort soll und kann man nichts eingeben - das macht ja der Code.
    Anschliessend an Deinen Code geht das Füllen des Labels mit diesem einzeiligen Befehl >
    Label1 = Knicklänge


    Gruss Urs
     
  8. Tiffiklotz

    Tiffiklotz Byte

    Erstmal Vielen Dank f&#252;r deine M&#252;he, vllt. hast du ja noch mehr Zeit und Lust... :)

    Also ich versuch mal den Zusammenhang etwas zu erkl&#228;utern, dass kannst du das besser nachvollziehen!

    Es geht um ein Pr&#252;fverfahren von W&#228;nden, dass nur angewendet werden darf, wenn 5 Zahlenwerte einen gewissen Wert(-ebereich) nicht &#252;berschreiten.
    Dies soll im ersten Schritt &#252;berpr&#252;ft werden und der User soll &#252;ber MsgBox benachrichtigt werden. Das habe ich so gel&#246;st, und es klappt:
    Code:
    Private Sub CommandButton1_Click()                                  '&#220;berpr&#252;fung: Verfahren geeinet?
    
        If Wanddicke >= 115 And LichteGeschossh&#246;he <= 275 And VerkehrslastDerDecke <= 5 And Geb&#228;udeh&#246;he <= 20 And Deckenst&#252;tzweite <= 600 Then
            MsgBox "Das vereinfachte Verfahren ist geeignet!"
        Else
            MsgBox "Das vereinfachte Verfahren ist nicht geeignet!"
        End If
    
    End Sub
    Im zweiten Schritt soll der User angeben (&#252;ber 2 OptionButton[JA/NEIN]) ob es sich bei der Wand um eine gro&#223;fl&#228;chige Wand oder einen kleinfl&#228;chigen Pfeiler handelt, davon ist n&#228;mlich der Abminderungsfaktor1 abh&#228;ngig. Das habe ich versucht so zu l&#246;sen. Ob es klappt, wei&#223; ich nicht, da ich mit der Ausgabe wie gesagt Probleme habe:

    Code:
        If OptionButton3 = True Then                                        'Abminderungsfaktor 1
            Abminderung1 = 0.8
        ElseIf OptionButton4 = True Then
            Abminderung1 = 1
        End If
    Anschlie&#223;end, also nach dem Ankreuzen eines OptionButtons, soll der User &#252;ber einen CommandButton "Berechnen" o.&#196;. eine Reihe von Werten ausgegeben bekommen. Einer davon den oben genannten Knickl&#228;ngenbeiwert.
    Mit diesem Knickl&#228;ngenbeiwert und einer der Eingaben (s. oben) soll die Knickl&#228;nge berechnet und ausgegeben werden. Mit der Ausgabe &#252;ber Label habe ich Probleme :confused:

    Code:
        Knickl&#228;nge = LichteGeschossh&#246;he * Knickl&#228;ngenbeiwert               'Berechnung Knickl&#228;nge
        
        Label15 = Knickl&#228;nge                                              'Ausgabe Knickl&#228;nge
    Code:
    Private Sub Label15_Click()
        Label15 = Knickl&#228;nge
    End Sub
    Oder kommt die Ausgabe gar nicht in den Bereich des CommandButtons? :confused:

    Au&#223;erdem muss noch ein zweiter Abminderungsfaktor berechnet werden, was glaube ich bisher nicht geklappt hat:

    Code:
            If (Knickl&#228;nge / Wanddicke) <= 10 Then Abminderung2 = 1               'Berechnung Abminderungsfaktor2
        If (Knickl&#228;nge / Wanddicke) > 10 Then Abminderung2 = 2
    Ich habe es auch versucht, das zweite if durch ein else zu ersetzen, ja in diesem fall ja nur entweder/oder geht...

    Anschlie&#223;end soll das Produkt der beides Abminderungsfaktoren ausgegeben werden... (also wieder &#252;ber Label anstatt &#252;ber TextBox)


    Momentan sieht mein Programm so aus:
    (vllt. habe ich einige Sachen ja auch einfach an die falsche Stelle gesetzt) :confused:

    Code:
    Dim Wanddicke As Single                                             'Variablendeklaration
    Dim LichteGeschossh&#246;he As Single
    Dim VerkehrslastDerDecke As Single
    Dim Geb&#228;udeh&#246;he As Single
    Dim Deckenst&#252;tzweite As Single
    Dim Knickl&#228;ngenbeiwert As Single
    Dim Knickl&#228;nge As Single
    Dim Abminderung1 As Single
    Dim Abminderung2 As Single
    Dim Abminderungsfaktor As Single
    
    
    Private Sub CommandButton1_Click()                                  '&#220;berpr&#252;fung: Verfahren geeinet?
    
        If Wanddicke >= 115 And LichteGeschossh&#246;he <= 275 And VerkehrslastDerDecke <= 5 And Geb&#228;udeh&#246;he <= 20 And Deckenst&#252;tzweite <= 600 Then
            MsgBox "Das vereinfachte Verfahren ist geeignet!"
        Else
            MsgBox "Das vereinfachte Verfahren ist nicht geeignet!"
        End If
    
    End Sub
    
    Private Sub CommandButton2_Click()
    
    
        If Wanddicke <= 175 Then                                            'Knickl&#228;ngenbeiwert
            Knickl&#228;ngenbeiwert = 0.75
        ElseIf Wanddicke <= 250 Then
            Knickl&#228;ngenbeiwert = 0.9
        Else
            Knickl&#228;ngenbeiwert = 1
        End If
        
        Knickl&#228;nge = LichteGeschossh&#246;he * Knickl&#228;ngenbeiwert               'Berechnung Knickl&#228;nge
        
        Label15 = Knickl&#228;nge                                              'Ausgabe Knickl&#228;nge
        
        If OptionButton3 = True Then                                        'Abminderungsfaktor 1
            Abminderung1 = 0.8
        ElseIf OptionButton4 = True Then
            Abminderung1 = 1
        End If
        
            If (Knickl&#228;nge / Wanddicke) <= 10 Then Abminderung2 = 1               'Berechnung Abminderungsfaktor2
        If (Knickl&#228;nge / Wanddicke) > 10 Then Abminderung2 = 2
        
        Abminderungsfaktor = Abminderung1 * Abminderung2                   'Berechnung Abminderungsfaktor
        
    
    End Sub
    
    Private Sub Label15_Click()
        Label15 = Knickl&#228;nge
    End Sub
    
    Private Sub TextBox1_Change()
        Wanddicke = TextBox1.Value
    End Sub
    
    Private Sub TextBox2_Change()
        LichteGeschossh&#246;he = TextBox2.Value
    End Sub
    
    Private Sub TextBox3_Change()
        VerkehrslastDerDecke = TextBox3.Value
    End Sub
    
    Private Sub TextBox4_Change()
        Geb&#228;udeh&#246;he = TextBox4.Value
    End Sub
    
    Private Sub TextBox5_Change()
        Deckenst&#252;tzweite = TextBox5.Value
    End Sub
    
    
    Private Sub UserForm_Click()
    
    End Sub
    
     
    Last edited: Oct 11, 2009
  9. Urs2

    Urs2 Megabyte

    Hallo Tiffiklotz,

    Ich werde mich heute Abend damit befassen, aber vorerst einige Fragen >

    1. Das Ganze findet ausschliesslich in einem VBA-UserForm statt ?

    2. Im Prinzip muss zuerst nur Wandstärke und Geschosshöhe eingegeben werden > dann entscheidet die Prüfung, ob es weiter gehen kann, oder ob alles abgebrochen werden muss ?

    3. Der User kann auch alle Eingaben machen, wenn die Prüfung in 2. dann nicht bestanden wird... wird trotzdem abgebrochen ?

    3. Hast Du meine Antwort in anderen Thread gesehen?
    Dort ist der Einzeiler, der zwei sich gegenseitig ausschliessende Möglichkeiten verarbeitet.

    4. Das ist aber nicht der ganze Code ?
    Deckenlast, Stützweite oder Gebäudehöhe werden ja nicht weiter verarbeitet...

    5. Wie geht denn die Abminderung in die Berechnung ein?

    Das was ich bis jetzt sehe, könnte in einem einzigen Sub, mit einem einzigen "Berechnen"-Button zusammengefasst werden.
    Weitere umfangreiche Berechnungen dann wohl besser in einem weiteren Sub/Function...
    ...das aber direkt vom ersten Sub aufgerufen wird, ohne menschliches Handeln...

    NB1 > Ich gebe prinzipiell allen Steuerelementen einen aussagekräftigen Namen (cbnBerechnen, lblKnicklänge usw). Das hantieren mit Textbox17 , Label15 oder CommandButton4 ist mir zu fehlerträchtig...

    NB2 > Ich habe zwar schon seit Jahrzehnten nichts mehr mit Statik zu tun gehabt... aber der Knicklängenbeiwert...
    ...ist es tatsächlich so >>> "Je dicker die Wand, um so grösser die Knicklänge" ??

    Gruss Urs
     
  10. Hascheff

    Hascheff Moderator

    Hallo Tiffiklotz,
    du machst immer wieder den gleichen Fehler, den ich dir schon in #3 erklärt habe und auf den Urs auch hinweist:
    Aber du hast es schon selbst erkannt,
    nur die speziellen Syntax-Anforderungen von VBA sind dir in die Quere gekommen.
    Code:
    If (Knicklänge / Wanddicke) <= 10 Then 
       Abminderung2 = 1
       Else Abminderung2 = 2
       End If
    Das Gleiche gilt für den OptionButton3/4. Du brauchst nur einen Button.
    Code:
    If OptionButton3 = True Then
       Abminderung1 = 0.8
       Else Abminderung1 = 1
       End If
     
  11. Tiffiklotz

    Tiffiklotz Byte

    @Hascheff, bzgl. OptionButton:
    Das Programm soll so benutzerfreundlich sein, wie es nur geht.
    Und als Benutzer finde ich es angenehmer, wenn ich f&#252;r jede m&#246;gliche Antwort (Ja/Nein) einen Button habe.
    Deshalb dachte ich mir, dass ich zwei Buttons machen, die sich gegenseitig ausschlie&#223;en. Und je nachdem welcher markiert wird, &#228;ndert sich "Abminderung1"

    @Urs: Ich habe dir mal eine Private Nachricht &#252;ber&#180;s Forum geschickt. Ich hoffe, du liest sie.
    @Urs: #2 bzgl. "ganzes Programm"?
    Das ist bisher nur ein kleiner Teil. Deckenlast und -St&#252;tzweite werden bisher(!) nur f&#252;r die Abfrage ben&#246;tigt, die entscheidet, ob das Programm starten kann oder abgebrochen werden muss.
     
    Last edited: Oct 11, 2009
  12. Urs2

    Urs2 Megabyte

    Hallo Matthias.... (gefällt mir besser als Tiffklotz...)

    Deine PN ist angekommen - wir machen nur hier weiter.

    Wenn das Ganze "so benutzerfreundlich wie möglich" sein soll, dann besteht ein grosser erster Teil des Codes zwingend nur aus dem Abfangen von allen denkbaren Eingabefehlern... die User entwickeln da immer ungeahnte Fähigkeiten...
    Frei nach Murphy > Wenn man rein theoretisch einen unsäglichen Mist eintippen könnte... dann werden sie das auch tun !


    Hascheff wollte nicht den 2. OptionsButton weglassen, sondern nur einen abfragen > dann zeigt der andere ja das Gegenteil !
    Wenn der Code selbst die 2 Möglichkeiten berechnet ist das perfekt, bei den OptButtons kommt aber der User ins Spiel >

    Entweder wird eine Option als Default vorgegeben...
    ...dann übersieht der User vielleicht seine nötige Eingabe... oder er "denkt", das sei wohl richtig so.

    Oder beide OptButtons sind beim Start nicht aktiviert...
    ...dann muss man beide Buttons abfragen... ob der User überhaupt etwas geklickt hatte.


    Code:
    If Wanddicke >= 115 And LichteGeschosshöhe <= 275 And VerkehrslastDerDecke <= 5 And Gebäudehöhe <= 20 And Deckenstützweite <= 600 Then  
    Hier hast Du 3 verschiedene Längeneinheiten >>> mm + cm (+ Tonnen) + m + wieder cm...
    Da überforderst Du den User bei der Eingabe, das gibt Aerger...
    ...nachher dividierst Du für Abminderung2 ja sogar selbst schon cm durch mm...

    Leg Dich auf eine Längeneinheit fest und schreibe gross ins Form "Alle Längeneinheiten in Metern" ... oder cm/mm... so wie üblich in Deinem Baubereich.


    Auf die TextBox_Change Subs würde ich verzichten... da hat man schneller einen Zirkelverweis, als man denken kann.


    Meine Fragen solltest Du schon beantworten > Findet jetzt alles im VBA-UserForm statt ?
    Ich gehe jetzt einmal davon aus und würde dann so vorgehen >>>

    Das Form hat 5 Textboxen und 2 OptButtons für die Eingabe, eine Reihe Labels für die Ausgabe und zumindest zwei CommandButtons für "Berechnen" und "Abbrechen".

    Der User macht seine 6 Eingaben und klickt auf "Berechnen". Der Code macht dann der Reihe nach >

    1. den Inhalt aller Eingaben in 7 Variable speichern

    2. alle Eingaben auf Plausibilität prüfen > zB gar keine Eingabe, Zahl/Text oder sinnvolle Grösse der jeweiligen Zahlen (5mm oder 5m dicke Wände...) und der Zahlen untereinander (Geschoss 8m, Gebäude 7m hoch...)

    3. wenn entsprechende Zahlen plausibel sind, prüfen, ob für dieses Verfahren geeignet

    4. Fehleingaben anmeckern oder sonstige Mitteilungen

    > erst jetzt beginnt die Rechenarbeit...

    5. die bis jetzt bekannten Ausgabe-Werte werden berechnet und in die Labels geschrieben

    6. falls die noch unbekannten Berechnungen umfangreich sein sollten, werden diese, der Uebersichtlichkeit wegen, in getrennte Sub/Functions geschrieben...
    ...und dort automatisch aufgerufen... und deren Resultate dann ins Form geschrieben


    Kannst Du im UserForm ein Label setzen und zB gelb anmalen ?
    Dann könnte man die Fehlermeldungen und Mitteilungen dort hineinschreiben... und auf die MsgBoxen verzichten.
    Der User sieht dann die Meldung und kann entsprechend ändern...
    ...während er die MsgBox zuerst wegclicken muss... und dann vergessen hat... was dort stand...


    Entspricht das etwa dem was Du willst ?

    Gruss Urs
     
  13. Tiffiklotz

    Tiffiklotz Byte

    Hey Urs,

    du bekommst erstmal nur eine 'knappe Antwort', da ich gleich zur Arbeit muss. Mehr dann Heute Abend!

    Ja, alles soll in einer VBA-UserForm stattfinden. Die Einheiten werde ich korrigieren. Ich hatte es vorerst so, dass keine Dezimalzeichen benötigt werden, aber du hast vollkommen Recht!
    Wenn die Prüfung nicht bestanden wird, ist das angewendete Verfahren nicht zulässig! Insofern ist es nur konsequent, auch bei vollständiger Eingabe, jedoch nicht bestandener Prüfung, das Programm zu beenden.

    Dein Programmablauf, den du über mir geschrieben hast, ist korrekt.
    Labels einfärben müsste ich hinbekommen, denke ich.
    (Auf der linken Seite ist ja dieses Eigenschaften-Feld, wo der Farbcode drin steht. Welche art von Code ist es? CMYK? ich kenne nämlich sonst nur RGB´s :( )

    Ich muss nun erstmal etwas fleißig sein und komme Heute Abend wieder online!
    Bis dann, Lieben Gruß
    Matthias
     
  14. Tiffiklotz

    Tiffiklotz Byte

    Da das Programm insgesamt noch um einiges komplexer wird als es bisher ist, habe ich mir noch mal ein paar grundlegende Gedanken gemacht:

    Schritt 1)
    Variablendeklaration.
    Code:
    Dim Variable as ###
    Bisher habe ich alle Variablen als single deklariert. Hat es Vorteile, einige als Integer zu deklarieren? In den Vorlesungen haben wir es oft so gemacht ...

    Schritt 2)
    Der Benutzer gibt alle notwendigen Werte ein, nicht nur die zur Pr&#252;fung notwendigen. Links ein beschriftetes Label, rechts davon ein Textfeld zur Eingabe.

    (vorrausgesetzt, die Eingaben wiedersprechen sich nicht, geht es weiter. Diverse Pr&#252;fungen zur Korrektheit m&#252;ssen eingebaut werden)

    Schritt 3)
    Das Programm &#252;berpr&#252;ft, ob das Pr&#252;fverfahren &#252;berhaupt anwendbar ist.
    Code:
    Private Sub CommandButton1_Click()                                  '&#220;berpr&#252;fung: Verfahren geeinet?
    
        If Wanddicke >= 115 And LichteGeschossh&#246;he <= 275 And VerkehrslastDerDecke <= 5 And Geb&#228;udeh&#246;he <= 20 And Deckenst&#252;tzweite <= 600 Then
            MsgBox "Das vereinfachte Verfahren ist geeignet!"
        Else
            MsgBox "Das vereinfachte Verfahren ist nicht geeignet!"
        End If
    
    End Sub
    Schritt 4)
    Berechnung n&#246;tiger Werte mit Hilfe der Eingaben.
    Notwendig

    Knickl&#228;ngenbeiwert:
    Code:
        If Wanddicke <= 175 Then                                            'Knickl&#228;ngenbeiwert
            Knickl&#228;ngenbeiwert = 0.75
        ElseIf Wanddicke <= 250 Then
            Knickl&#228;ngenbeiwert = 0.9
        Else
            Knickl&#228;ngenbeiwert = 1
        End If
    Knickl&#228;nge = LichteGeschossh&#246;he * Knickl&#228;ngenbeiwert
    Abminderung1: k1 = 1 (Wenn Wand kein Pfeiler, sonst k1=0,8) --> Abfrage &#252;ber OptionButtons
    Abminderung2:
    Abminderungsfaktor: k=k1*k2
    SigmaNull: SigmaNull ist abh&#228;ngig von der Steinfestigkeitsklasse und der M&#246;rtelgruppe. Ich habe eine Tabelle mit 10*5 Zellen und entsprechenden Werten. Diese soll in Excel &#252;bertragen werden und von VBA aus dieser Tabelle abgefragt werden :confused::confused:
    vorh.Sigma:
    zul.Sigma:

    Schritt 5)
    Nachweis: Es wird vorh-Sigma mit zul.Sigma verglichen udn eine entsprechende Meldung ausgegeben.

    ______________________________________________
    So, nun setz ich mich nochmal etwas ran und schaue, was ich selbst hinbekomme. Die Abfrage aus Excel kann ich definitiv nicht! :(
     
  15. Tiffiklotz

    Tiffiklotz Byte

    'Tschuldigung, dass ich nocheinmal posten muss, aber editieren ist nach mehr als 60 Minuten leider nicht mehr möglich.

    Ich habe noch einmal neu begonnen, und schon einiges geschafft, wie ich finde. Ich habe aber noch einige Fragen:

    1) Wie mache ich die Ausgabe über Labels?
    So etwa?
    Code:
    Private Sub Label_Change()
        Label.Value = Knicklänge
    End Sub

    2) Ich habe einige Überprüfungen eingebaut. Wie kann ich es machen, dass, wenn die Eingaben nicht OK sind, das Programm nicht weiter läuft? Bisher erscheinen immer alle Textboxen, die ich eingebaut habe.
    Wenn jedoch die Eingaben nicht OK sind, muss nicht geprüft werden, ob das Verfahren geeignet ist. In diesem Fall muss der User die Daten neu eingeben.

    3) Ich soll aus zwei Werten, vorgegeben in einer Exceltabelle (Steinfestigkeitsklasse/Mörtelgruppe) einen Dritten Wert (SigmaNull) bestimmen. Dieser Wert ist auch in der Tabelle vorgegeben. Mit Hilfe des VBA Codes soll auf die Tabelle zugegriffen werden. Ich brauche Hilfe :bitte:
    (Stichworte in der Aufgabe: "Range- oder Cells-Eigenschaft")

    4) Wie mache ich es, dass eine Fehlermeldung erscheint, wenn nicht alle Eingaben gemacht wurden?
     
  16. Urs2

    Urs2 Megabyte

    Hallo Matthias,

    Google richtig gefüttert führte mich zu "DIN 1053-1 Mauerwerk"
    Das ist ja einiges umfangreicher als ich dachte... komm ja nicht in Zeitnot !

    Es ist schon lange her... aber wenn ich das so schnell betrachte, müssten noch mindestens 2 Eingabefelder dazukommen >
    - die Wandlänge um Mauer und Pfeiler zu trennen, und um das Ausschlusskriterium <400cm2 zu berechnen
    - die Mörtelklasse für Druckfestigkeit

    Ich gehe zuerst auf Deine Fragen ein, und gebe Beispiele dann im nächsten Beitrag.

    > Variable deklarieren
    VBA verlangt weder eine Deklaration noch eine Dimensionierung der Variablen (im Gegensatz zu VB).
    Jedes Wort im Code, das VBA noch nicht kennt, wird einfach als Variable As Variant angenommen. Das ist praktisch bei kurzen Subs, hat aber auch Nachteile bei vielen Variablen >
    Wenn Du Dich bei der deklarierten Variablen LichteGeschossHöhe im Code vertippst als LickteGeschossHöhe, sagt VBA nichts und nimmt an, das sei eine neue Variable... und Du suchst dann, warum der Code nicht funktioniert...

    Schreib zuoberst, oberhalb Deiner Dim-Deklarationen die Zeile
    Option Explicit
    ...dann müssen alle Variablen-Namen deklariert sein (aber nicht die Dimension As Etwas). Jeder Fehler wird dann schon beim Kompilieren angemeckert.

    Da Du nicht weisst, auf welchen (Sprach)-Systemen Dein Ding laufen wird, würde ich vorsichtshalber im Code auf Umlaute verzichten.

    > Ort der Variablen-Deklaration
    Zuoberst, ausserhalb eines Subs (wie bei Dir) sind sie für alle Subs innerhalb des Moduls les- und beschreibbar (wie es bei Dir sein soll)
    Innerhalb eines Subs deklariert, sind sie nur innerhalb dieses Subs gültig

    > Integer, Single, Double, Decimal....
    Diese Aufteilung stammt wohl aus der Zeit, als im Speicher um jedes Bit gestritten werden musste, bei den heutigen GB-Speichern...
    Ausser in Spezialfällen gebe ich Ihnen keine vordefinierte Dimension, der Aerger den man sich einhandelt ist für mich grösser, als der, den man damit verhindern möchte... VBA macht sie dann einfach zu Variant.
    10 wird dann automatisch zu Variant/Integer, geteilt durch 4 dann zu 2.5 As Variant/Double.
    Wenn ein User Buchstaben anstatt Zahlen eintippt, ergibt das einen Laufzeitfehler in der VariablenAsInteger, der AsVariant ist das egal.

    > Mörteltabelle
    Kein Problem, die Tabelle kommt in ein Excel-Blatt und der Code holt sich dort die Entsprechung für den gegebenen Mörteltyp.
    Dazu muss der Typ aber vom User eingegeben werden...
    Später...

    > Färben der Label
    Eigenschaften > BackColor >> Klick aufs Feld daneben > Dropdown > Farbpalette > auswählen

    >> Ich würde nochmals genau abklären, wieviele/welche UserEingaben nötig sind und welche Ausgaben ins Form gemacht werden müssen. Nicht dass später der Code umgeschrieben, oder das Form wieder geändert werden müssen.

    >> Wenn das Form geschlossen wird, sind die schönen Rechenresultate weg...
    ...das Ganze soll doch sicher auch noch in ein Tabellenblatt geschrieben werden ??
    Kann man nachher noch machen...

    >> Für Steinfestigkeit- und Mörtelklassen sind die Auswahl-Möglichkeiten ja vorgegeben.
    Da würde ich keine Textbox nehmen, sondern einen Dropdown (=Kombinationsfeld) mit den Vorgaben füllen.
    Dann sind skurrile Eingaben unmöglich...

    Ich denke, so würde das gut gehen >
    - das "Sub Berechnen" macht die ganzen Eingaben- und Ausschlussprüfungen, ruft zB den Wert aus der Tabelle ab, füllt alle Variablen mit Daten (die es in anderen Functions berechnen lässt), prüft ggf nochmals und schreibt dann alles ins UserForm oder ins Arbeitsblatt
    - die einzelnen Functions berechnen nur einen einzelnen Wert
    Im Gegensatz zu Subs, geben Functions das Resultat an den Aufrufer zurück.

    So hättest Du mehrere Baustellen zum Bearbeiten und mehr Uebersicht...

    Gruss Urs
     
  17. Urs2

    Urs2 Megabyte

    ...weiter...

    Ich hoffe, Du verstehst mein abgekürztes Beispiel >
    Code:
    Option Explicit
    
        'EingabeVariablen ohne Dimension, User kann Buchstaben tippen...
    Dim Wanddicke                                             'Variablendeklaration
    Dim LichteGeschosshöhe
    Dim Verkehrslast
    Dim Gebäudehöhe
    Dim Stützweite
    Dim Steinfestigkeitsklasse As Integer
    Dim Mörtelgruppe As Variant
    Dim Abminderung1 As Single
    Dim Abminderung2 As Single
    Dim Abminderungsfaktor As Single
    Dim Knicklänge As Single
    Dim Knicklängenbeiwert As Single
    Dim SigmaNull As Single
    Dim VorhSigma As Single
    Dim ZulSigma As Single
    
    
    Private Sub Cmd_Berechnen_Click()                                   'Berechnungen:
    
            'zuerst alte Fehlermeldung löschen
    lblError = ""
            'alle Usereingaben einlesen
            'beim Schreiben merkst Du, dass kurze, prägnante VariablenNamen sinnvoll wären
    Wanddicke = Tbx_Wanddicke
    LichteGeschosshöhe = Tbx_LiGeschoss
            'bei OptButtons beide abfragen (das wäre > AbmindJ As Boolean)
    AbmindJ = Opt_Ja
    AbmindN = Opt_Nein
    'usw für alle Eingaben
    '
    '
    '
            'dann die Falscheingaben filtern
        If IsNumeric(Wandicke) = False Then
                    'wenn keine Zahl
            errMess = "Wanddicke ist keine Zahl"
                    'geht direkt zur Sprungmarke ErrMessage am Ende des Subs
            GoTo errMessage
        ElseIf Wanddicke < 11.5 Or Wanddicke > 200 Then
                    'glaube <11.5cm nicht zulässig als Tragwand...
                    'vbCr ist Zeilenschaltung
            errMess = "Sie haben eine ungültige Wanddicke eingegeben." & vbCr & _
                        "Bitte überprüfen sie Ihre Eingaben." & vbCr & _
                        "Gültig von 13.5 bis 20cm"
            GoTo errMessage
        End If
        
        If AbmindJ = False And AbmindN = False Then
                    'wenn kein OptButton geklickt
            errMess = "Abminderung XXX > Sie haben keinen Button geklickt"
            GoTo errMessage
        ElseIf AbmindJ = True Then
            Abminderung1 = 0.8
        Else: Abminderung1 = 1
        End If
    'und so weiter für alle Eingaben
    '
    '
    '
    'dann sinngemäss die Ausschlussbedingungen berechnen
    'auch ggf mit errMess und GoTo errMessage
    '
    '
    '
    '
        'jetzt die einzelnen Functions aufrufenzum Füllen der Variablen zB >
    Knicklänge = FuncKnicklängebeiwert
    'usw
    '
    '
    '
    
        'jetzt Labels im Userform füllen
    lblZZZ = Abminderung1
    lblYYY = Abminderung2
    lblXXX = Knicklänge
    'usw für alle Labels
    '
    '
    '
        
        
        Exit Sub                'wenn kein Fehler > hier Ende
        
                    'hier Sprungmarke für Fehlerbehandlung
    errMessage:
                'das lblError muss im Form sein, für die FehlerAusgaben
                'füllt das Label mit entsprechender Fehlerbeschreibung
        lblError = errMess
    
    End Sub
    
            'Beispiel für Functions
    
    Function FuncKnicklängebeiwert()
            'gibt den Beiwert ans aufrufende "Sub Berechnen" zurück
        If Wanddicke <= 175 Then                                        'Knicklängenbeiwert
            FuncKnicklängenbeiwert = 0.75
        ElseIf Wanddicke <= 250 Then
            FuncKnicklängenbeiwert = 0.9
        Else
            FuncKnicklängenbeiwert = 1
        End If
    
    End Function
    
    - es hat jetzt nur das Sub Berechnen, so als "Koordinator" und die einzelnen Functions für die einzelnen Berechnungen

    - die Functions könnte man natürlich auch noch ins Sub einbauen, aber ich denke das würde dann zu unübersichtlich und nur nach langem Studieren verständlich.
    Es müssen ja fremde Leute den Code verstehen, die ihn noch nie gesehen hatten...

    Gruss Urs


    PS > Die Functions muss ich nochmals überdenken.
    Zumindest das Beispiel braucht ja gar keine Rückgabe zu machen, es kann ja selbst die Variable füllen

    Einfach aufrufen mit einem Wort in einer Zeile >
    FuncKnicklängebeiwert

    und die Function dann so schreiben >
    Code:
    Function FuncKnicklängebeiwert()
            'gibt den Beiwert ans aufrufende "Sub Berechnen" zurück
        If Wanddicke <= 175 Then                                        'Knicklängenbeiwert
            Knicklängenbeiwert = 0.75
        ElseIf Wanddicke <= 250 Then
            Knicklängenbeiwert = 0.9
        Else
            Knicklängenbeiwert = 1
        End If
    
    End Function
    ...dann füllt sie die Variable und gibt zurück ins Sub Berechnen
     
    Last edited: Oct 13, 2009
  18. Tiffiklotz

    Tiffiklotz Byte

    Okay, also wenn ich dich richtig verstanden habe, empfiehlst du mir folgendes Vorgehen:

    - L&#246;schen meiner bisherigen Pr&#252;fungen (If FEHLER then msgbox) und Ersetzen durch (errMess GoTo errMessage)

    - Was du in deinem Beispiel am Anfang des Codes hast ( 'alle Usereingaben einlesen
    Wanddicke = Tbx_Wanddicke), hat mein Code am Ende, da ich es &#252;ber die User-Form (Doppelklicken auf die Textbox) eingegeben habe. Schlimm/Unempfehlenswert?

    Hei&#223;t das, dass AbmindJ/N in deinem Beispiel neue Variablen sind?
    Ich habe es ja anders gemacht: If Opt_Ja=True Then Knickl&#228;ngenbeiwert ....

    - Mit der Fl&#228;che der Wand hast du Recht. Wir haben aber eine Beispielrechnung (auf Papier) bekommen, auf der das auch nicht weiter ber&#252;cksichtigt wird. Ich denke, in diesem Fall ist es eine notwendige Vorarbeit des Anwenders, die Fl&#228;che der Wand zu bestimmen. Ich werde dann bei den OptButtons ein beschriftetes Label hinsetzen, auf dem die Bedingung f&#252;r Wand/Pfeiler kurz erl&#228;utert sind.

    - Kann man eigentlich die Eigenschaften der Schrift auf Labels (Gr&#246;&#223;e/Fett/Kursiv usw...) &#228;ndern?

    - Was ist der Vorteil von Functions?
    Ich kenne es nur so, einen Wert ausrechnen zu lassen und ihn dann per Label/MsgBox ausgeben zu lassen...

    So, nun muss ich erstmal wieder zur Arbeit und heute Abend habe ich dann eine Menge zu tun! :)
     
  19. Urs2

    Urs2 Megabyte

    Hallo Matthias,

    Du musst beschliessen, ich kann Dir nur raten...

    - MsgBoxen beim geöffneten Form... das widerstrebt mir, ich habe ja schon eine schöne Anzeigefläche vor mir...

    - Txt_Change-Ereignis > Habe ich noch nie gemacht und noch nirgends gesehen... der User muss den Berechnen-Button dann ja doch drücken. Was das alles noch für unbekannte Auswirkungen haben könnte, weiss ich nicht...
    Der PC ist so ständig am Rechnen... für nichts.
    12345 eintippen heisst ja > die Variable wird zuerst auf 1 gesetzt, dann auf 12, dann auf 123.........

    - AbmindJ... sind neue Variablen, weil ich beide OptButtons auslese... um zuerst zu prüfen... ob überhaupt einer ausgewählt wurde

    - Fläche der Wand > ich dachte vor allem an Länge x Stärke < 400cm2, das wäre ein Ausschlusskriterium

    - Schrift-Format > in den Eigenschaften kannst Du neben Font Schrift/Grösse/Firlefanz und neben ForeColor die Schriftfarbe einstellen

    - Functions tun das gleiche wie Subs, aber sie geben einen Rückgabewert an den Aufrufer. In Excel>Extras>Makros werden sie nicht angezeigt. Gestartet werden sie nur über VBA-Code oder über eine Formel in einer Excel-Zelle

    Gruss Urs
     
  20. Tiffiklotz

    Tiffiklotz Byte

    Das ist eine Menge Input. Ich versuche das mal Stück für Stück zu verarbeiten. Momentan schreibe ich den Code für alle Überprüfungen.

    Erstmal wieder ein paar Fragen:

    - Eingaben: Die Eingaben habe ich geändert.
    Vorher:
    Code:
    Private Sub Tbx_Wanddicke_Change()
        Wanddicke = Tbx_Wanddicke.Value
    End Sub
    Jetzt:
    Code:
    Wanddicke = Tbx_Wanddicke
    Der Effekt ist der Selbe? :)

    - ComboBoxen: Wie füge ich Auswahlmöglichkeiten ein?
    Ich habe eine Excel-Tabelle mit den Werten für die ComboBox. Man kann sich das etwa so vorstellen:
    x-Wert: (A2:A11) (von VBA in ComboBox einzulesen) [Steinfestigkeitsklase]
    y-Wert: (C1:G1) (von VBA in ComboBox einzulesen) [Mörtelgruppe]
    z-Wert: (B2:G11) teilweise vorhanden (von VBA abzufragen und den z-Wert für weitere Berechnungen verwenden) [SigmaNull]

    - ComboBoxen: Wie mache ich dem Code klar, dass es sich bei den eingelesenem Wert um die Steinfestigkeitsklasse/Mörtelgruppe handelt?

    - Überprüfungen: Ich habe die Überprüfungen nun nach deinem Stil verarbeitet. Ich verwende "errMess"und "GoTo errMessage". Ich muss doch auch noch eine ErrorMessage definieren, oder wie funktioniert das?

    - Überprüfungen: Folgenden Code habe ich für alle Zahlen-Eingaben variiert. Ich denke, dass das alles funktionieren sollte. Bisher bin ich noch nicht zum Programm-Testen gekommen. Zu folgendem Code habe ich aber noch eine Frage:
    Was mache ich da falsch? Die Zeile versteht der Code nicht. Ich möchte, dass eine ErrorMessage erscheint, wenn der für die Geschosshöhe eingegebene Wert größer/gleich dem Wert für die Gebäudehöhe ist.

    - Überprüfungen: Die Abfrage, ob das Verfahren geeignet ist, schreibe ich in den gleichen PrivateSub? (Cmd_Uerberpruefen)
    Code:
        If Wanddicke >= 11.5 And LichteGeschosshoeöhe <= 275 And Verkehrslast <= 5 And Gebaeudehoehe <= 2000 And Stuetzweite <= 600 Then ...
    
    Wenn diese Fragen geklärt sind, kümmere ich mich um die Berechnungen. Parallel zu den Berechnungen (oder ggf. schon zuvor) muss ich die Ausgaben schreiben, um die Korrektheit meiner Formeln zu überprüfen.

    Morgen geht´s weiter! Vielen Dank soweit. Lieben Gruß,
    Matthias
     
Thread Status:
Not open for further replies.

Share This Page