| Code Kitchen Allgemeines Coder-Forum rund um das Programmieren eigenständiger, ausführbarer Programme. |
Diskussion: Probleme in VBA mit der UCase Function im Forum Code Kitchen, in der Kategorie Software Home; Anzeige Ich habe ein Programm in VBA geschrieben um in Excel den U-Wert eines Bauteils zu berechnen. Dazu muss das ...
![]() |
| | #1 (permalink) |
| Registriert seit: 26.12.10 ![]() Likes: 0 | Anzeige Ich habe ein Programm in VBA geschrieben um in Excel den U-Wert eines Bauteils zu berechnen. Dazu muss das Programm die Wärmeleitzahl und die Dicke der einzelnen Schichten im Bauteil kennen. Zusätzlich fragt das Programm den Baustoff der einzelnen Schichten ab und ordnet sie der variable k zu, damit die Zahlen in der Tabelle den Baustoffen zugeordnet werden können. Ich dachte mir, dass es ja umständlich ist, wenn man für jeden einzelnen Baustoff immer die Wärmeleitzahl in Tabellen suchen muss, also habe ich eine Function geschrieben, die anhand einer Tabelle den Baustoffen die Wärmeleitzahl automatisch zuordnet. Dazu wird Die Bezeichnung des Baustoffs, die ja schon abgefragt wurde in die Function übergeben und dort mittels eines Select Case Befehls den entsprechenden Wärmeleitzahlen zugeordnet. Das Problem ist, wenn der eingegebene Baustoff in der Groß- und Kleinschreibung nicht den Baustoffen in der Tabelle entspricht, wird der Fall in der Tabelle übergangen und die Wärmeleitzahl nicht zugeordnet. Ich dachte eigentlich, dass ich das mit der UCase Function beheben kann. Dann würde ich in der Tabelle alles Groß schreiben und in der Sub, nach der Zuordnung des Baustoffs zur variable k schreiben: UCase(k) Dann müsste der Text in der Variable k ja eigentlich groß sein und es dürfte keine Probleme mehr geben, wenn k an die Function übergeben wird. Funktioniert aber nicht. Wenn die Variable k die Ucase Function durchlaufen hat, dann ist der text in Variable k immer noch klein geschrieben. Woran liegt das? |
| | |
| | #2 (permalink) | |
| Registriert seit: 30.01.10 ![]() ![]() Likes: 1 | Zitat:
Nun aber mal ernsthaft... woher sollen wir das wissen, wenn du nicht eine Zeile Code postest?!
__________________ Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rick Cook - | |
| | |
| HaBOT | - Anzeige - |
| |
| | #3 (permalink) | |
| Themenstarter Registriert seit: 26.12.10 ![]() Likes: 0 | Zitat:
Aber ich kann den Code ja trotzdem mal posten. Ich denke die meisten Befehle erklären sich aufgrund ihres Namen von selbst. Und das Programm an sich Funktioniert ja auch, nur halt dieses UCase nciht. Code: Public Sub U_wert()
Dim x, k As String, kk, n, nn, i, j, s, q, Rsi, w
'x=Anzahlder Schichten, b=Baustoff der Schichten, kk=Dicke Schicht,n=Wärmeleitzahl,nn=wärmewiderstand,i=Schleifenindex,j=Schleifenindex,q=Wärmestromrichtung,Rsi=Konstanter Übergangswiderstand innen
öffne_lösch_Tabelle "Ergebnis"
'Fragt die Zahl der Schichten ab
tipp_ein x, "Wie viele Schichten hat das Bauteil?"
If Not (Entspricht_Ganzzahl(x)) Then GoTo Fehler_a
'erzeugt das farbige Fenster in der richtigen Größe
For i = 1 To 6
Zeile_Spalte_Zellenfarbe 1, i, 41
Next i
For i = 1 To 6
For j = 2 To x + 6
Zeile_Spalte_Zellenfarbe j, i, 15
Next j
Next i
'Fügt fester Tete und Werte ein
Cells(1, 2) = "Baustoff"
Cells(1, 3) = "Dicke"
Cells(1, 4) = "Wärmeleitzahl"
Cells(1, 5) = "Wärmewiderstand"
Cells(2, 2) = "Rsi"
Cells(x + 3, 2) = "Rse"
Cells(x + 3, 5) = 0.04
'Ermittelt den richtigen Rsi Wert
tipp_ein q, "Ist der Wärmestrom (1)Aufwärts, (2)Horizontal oder (3)Abwärts gerichtet?"
Groß (q)
Select Case q
Case 1
Rsi = 0.1
Case 2
Rsi = 0.13
Case 3
Rsi = 0.17
Case Else
GoTo Fehler_b
End Select
Cells(2, 5) = Rsi
'Sonderfall es gibt nur eine Schicht im Bauteil
Select Case x
Case 1
tipp_ein_Text k, "Aus welchem Material ist das Bauteil?"
UCase (k)
tipp_ein kk, "Wie Dick ist das Bauteil?"
nn = kk / WL(k)
Cells(3, 2) = k
Cells(3, 3) = kk
Cells(3, 4) = WL(k)
Cells(3, 5) = nn
s = nn
Case 2 To 10
tipp_ein_Text k, "Aus welchem Material ist die erste Schicht im Bauteil?"
UCase (k)
tipp_ein kk, "Wie Dick ist die erste Schicht?"
For i = 1 To 6
Zeile_Spalte_Zellenfarbe 1, i, 41
Next i
Cells(3, 2) = k
Cells(3, 3) = kk
Cells(3, 4) = WL(k)
nn = kk / WL(k)
Cells(3, 5) = nn
s = nn
For i = 2 To x
tipp_ein_Text k, "Aus welchem Material ist die nächste Schicht im Bauteil?"
UCase (k)
tipp_ein kk, "Wie Dick ist die nächste Schicht?"
Cells(i + 2, 2) = k
Cells(i + 2, 3) = kk
Cells(i + 2, 4) = WL(k)
nn = kk / WL(k)
Cells(i + 2, 5) = nn
s = s + nn
Next i
End Select
Zeile_Spalte_Schriftfarbe x + 5, 4, 3
Zeile_Spalte_Schriftfarbe x + 5, 5, 3
Cells(x + 5, 4) = "U-Wert"
Cells(x + 5, 5) = 1 / (s + Rsi + 0.04)
Exit Sub
Fehler_a:
Beep
MsgBox ("Nur ganze Zahlen möglich")
Fehler_b:
Beep
MsgBox ("Erlaubte Eingaben:1,2,3")
End Sub
Public Function WL(k)
Dim n, ww
'k=Baustoff, n=Wärmeleitzahl, ww=Wärmeleitzahlmaximal
Select Case k
'Baustoffe
Case "Stahl unlegiert"
WL = 48
'ww = 58
Case "Stahl niedrig legiert"
WL = 42
Case "Stahl hochlegiert"
WL = 15
Case "Granit"
WL = 2.8
Case "Beton"
WL = 2.1
Case "Zementstrich"
WL = 1.4
Case "Kalkzement-Putz"
WL = 1
Case "Glas"
WL = 0.76
Case "Mauerziegel"
WL = 0.5
'ww = 1.4
Case "Holz"
WL = 0.09
'ww = 0.19
Case "Gummi"
WL = 0.16
Case "Poroton"
WL = 0.08
'ww = 0.45
Case "Porenbeton"
WL = 0.08
'ww = 0.25
Case "Lehm"
WL = 0.47
'ww = 0.93
Case "Sand"
WL = 0.58
Case "Sandstein"
WL = 2.3
Case "Mamor"
WL = 2.8
Case "Kalkstein"
WL = 2.2
Case "Epoxidharzmörtel mit 85 % Quarzsand"
WL = 1.2
'Dämmstoffe
Case "Aerogel"
WL = 0.02
Case "Schaumglas"
WL = 0.04
Case "Glasschaum-Granulat"
WL = 0.08
Case "Glaswolle"
WL = 0.032
'ww = 0.05
Case "Stroh"
WL = 0.038
'ww = 0.067
Case "expandiertes Polystyrol"
WL = 0.035
'ww = 0.05
Case "extrudiertes Polystyrol"
WL = 0.032
'ww = 0.04
Case "Polyethylen"
WL = 0.0034
'ww = 0.04
Case "Polyurethan"
WL = 0.024
'ww = 0.035
Case "Vakuumdämmplatte"
WL = 0.004
'ww = 0.006
Case "Kork"
WL = 0.035
'ww = 0.046
Case "Wolle"
WL = 0.035
Case "Perlit"
WL = 0.04
'ww = 0.07
Case "Mineralwolle"
WL = 0.035
'ww = 0.045
Case Else
tipp_ein WL, "Wärmeleitzahl"
End Select
End Function | |
| | |
| | #4 (permalink) |
| Registriert seit: 30.01.10 ![]() ![]() Likes: 1 | In dem Code wird die UCase-Funktion zwar aufgerufen, aber der Rückgabewert von UCase wird nicht behandelt. Die Routine arbeitet also mit dem alten Variablenwert weiter. So wäre es richtig: Code: Dim x as String
x = UCase("test") 'x beinhaltet nun "TEST"
__________________ Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rick Cook - |
| | |
| | #5 (permalink) |
| Themenstarter Registriert seit: 26.12.10 ![]() Likes: 0 | Aber wenn ich den Text als Argument in den UCase Befehl setzen muss, wie kann ich dann unterscheiden? Also ich will ja, dass das Programm, wenn ich z.B. Granit als Baustoff eingebe per WL Function die zugehörige Wärmeleitzahl raussucht. Das klappt auch, so lange ich Granit schreibe und nicht gRanit. Deswegen wollte ich ja in der Tabelle in der Function alle Baustoffe groß schreiben und dann den inhalt von k per UCase auch vergrößern. Wenn ich jetzt aber k=UCase(gRanit) schrieben muss, dann funktioniert es ja nciht, wenn ich dann z.B. Mineralwolle eingebe. Oder muss ich jetzt nach der EIngabeaufforderung von k eine richtig umständliche case select schreiben? Also so in der Art. Code: Select Case k
Dim k As String
Case "Stahl unlegiert"
k = UCase("Stahl unlegiert")
Case "Stahl niedrig legiert"
k = UCase("Stahl niedrig legiert")
Case "Stahl hochlegiert"
k = UCase("Stahl hochlegiert")
Case "Granit"
k = UCase("Granit")
Case "Beton"
k = UCase("Beton")
Case "Zementestrich"
k = UCase("Zementestrich")
Case "Kalkzement-Putz"
k = UCase("Kalkzement-Putz")
................. Mein Wunsch wäre es, dass es eine Prozedur eine Tabelle beinhaltet, in der alle Stoffkenngrößen dem Stoff zugeordnet sind, also nicht nur die Wärmeleitzahl, sondern auch Werte wie z.B. Dichte oder Biegefestigkeit. So dass ich mit verschiedenen Programmen auf die Prozedur zugreifen kann, und die Prozedur mir halt immer die erforderlichen Stoffkenngrößen ausgibt. Ich habe aber keine Idee, wie ich sowas anstellen könnte, da eine Function ja immer nur einen Wert ausgibt. |
| | |
| | #6 (permalink) |
| Registriert seit: 30.01.10 ![]() ![]() Likes: 1 | Mein Beispiel war einfach allgemein formuliert. Du kannst Variablen verwenden, wie du willst bzw. sie benötigst. Eine Variable ist ja, grob gesagt, nichts weiter als ein Container für einen Wert. Und ob du nun die Variable k der Funktion übergibst, oder Variable F oder direkt den Wert (z.B. "test") ist der Funktion egal. Code: Dim x as String Dim y as String x = "TeSt" y = UCase(x) Code: Dim x as String x = UCase(k) Evtl. geht in VBA auch folgendes Konstrukt (nicht getestet): Code: k = UCase(k) Wie du letzendlich dein Programm strukturierst bleibt dir überlassen. Da führen bekanntlich 1000 Wege nach Rom. Allerdings sollten Funktionen immer so minimalistisch wie möglich sein. Größere Arbeiten erledigt man in Prozeduren und Routinen und kleinere, immer wiederkehrende Arbeiten lagert man in Funktionen aus.
__________________ Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rick Cook - Geändert von Dresko (27.12.10 um 03:10 Uhr) |
| | |
| | #7 (permalink) |
| Themenstarter Registriert seit: 26.12.10 ![]() Likes: 0 | Alles klar, jetzt klappt es. Vielen Dank ![]() Jetzt habe ich aber gleich 2 neue Fragen. Das Programm ruft die Funktion mehrere Male auf z.B. hier Code: Cells(3, 4) = WL(k)
nn = kk / WL(k) Wenn in die Funktion ein k eingegeben wird, was auch in der Tabelle vorkommt, merkt man das gar nicht, aber ich habe ja in die Function als Case Else gesetzt, dass man dann die Wärmeleitzahl selbst eingeben muss. Das muss man dann aber 2 mal hintereinander, was ziemlich nervig ist. Kann man das irgendwie umgehen? Und meine 2. Frage bezieht sich darauf, dass du sagtest, dass man größere Sachen nciht in eine Function packt, sondern in Prozeduren und Routinen. Was sind Prozeduren und Routinen? Wo kann ich solche Dinge, von denen ich mal denke, dass sie eigentlich Basiswissen sind im Programmieren, nachlesen? Und wie kann ich, wenn ich z.B. die Tabelle in eine Prozedur schreibe und da mehrere Werte zu jedem Baustoff gespeichert habe, die Prozedur von meiner Sub aufrufen? |
| | |
| | #8 (permalink) | |
| Registriert seit: 30.01.10 ![]() ![]() Likes: 1 | Naja, da Funktionen meist für wiederkehrende Aufgaben gedacht sind, baut man normalerweise solch' ein Error-Handling an dieser Stelle auch nicht ein. Lass dir im Case Else-Zweig einfach 0,-1 oder 9999 oder sonst eine Zahl zurückgeben, sodass du weißt, dass es sich um einen Error-Wert handelt und behandel diesen außerhalb der Funktion. Außerdem macht es mehr Sinn die zurückgegebenen Daten zwischenzuspeichern, statt die Funktion ständig neu aufzurufen, wenn sich k nicht geändert hat. Aus deinem Beispiel: Code: Dim Result as String 'Programmiere WL so, dass -1 zurückgegeben wird, wenn nichts passt Result = WL(k) 'Überprüfen ob WL -1 zurückgeliefert hat If Result = "-1" Then 'Falls ja, lass den Benutzer einen Wert eingeben tipp_ein WL, "Wärmeleitzahl" 'Weise der Variable Result den eingegebenen Wert zu Result = Wärmeleitzahl End If 'Arbeite mit Result weiter... Cells(3, 4) = Result nn = kk / Result Zitat:
Als Beispiel (auf VBA bezogen): Du hast mehrere Buttons mit unterschiedlichen Aufgaben. Jeder ruft eine andere Sub-Prozedur auf. Eine Sub-Prozedur liest nun in einer Schleife nacheinander Werte aus einer Spalte aus, übergibt diese Werte nacheinander an eine Funktion, die etwas damit macht und einen anderen Wert zurückliefert. Diese andere Werte sollen nun in einer anderen Spalte ausgegeben und zudem einer ComboBox hinzugefügt und sortiert werden. Da man das Hinzufügen von Elementen zu einer ComboBox und das Sortieren derselbigen auch für andere Buttons gebrauchen könnte, würde es unter Umständen Sinn machen, diese Code in eine eigene Sub-Prozedur auszulagern, damit man ihn (genau wie eine Funktion) mehrfach aufrufen kann. Eine Funktion ist dafür jedoch unnötig, da man keinen Rückgabewert braucht. Diese ausgelagerte Sub-Prozedur, die nur eine Teilaufgabe löst, würde man als Routine bezeichnen. Auf die Schnelle hab ich zu VBA dieses Openbook gefunden. Vielleicht hilft's dir ja auf die Sprünge.
__________________ Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rick Cook - | |
| | |
![]() |
| - Anzeige - | |
| |
| Themen-Optionen | |
| Ansicht | |
| |