#WERT! und "Ein in der Formel verwendeter Wert ist vom falschen Datentyp."

  • Excel

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von Andreas_500.

    #WERT! und "Ein in der Formel verwendeter Wert ist vom falschen Datentyp."

    Hallo Community,
    die Fehlermeldung: „Ein in der Formel verwendeter Wert ist vom falschen Datentyp.“ und der Zellen-Inhalt #WERT! bringt mich zur Verzweiflung...

    Ich habe in Excel 2019 Professional eine VBA-Schnittstelle zu meiner Delphi-DLL. Die VBA besteht im Wesentlichen aus folgenden Teilen:

    Quellcode

    1. Option Explicit
    2. Option Base 1
    3. Private Declare Function BePu Lib "ChemWings.Flow.dll" _
    4. (ByRef Rohrleitung_Polynom_Koef_Vektor#, ByVal Anzahl_Werte_Rohr&, ByRef Pumpe_Polynom_Koef_Vektor#, ByVal Anzahl_Werte_Pumpe&, ByRef V_Strom_Betriebspunkt#) As Boolean
    5. ...
    6. Public Function Betriebspunkt(Rohrleitung_Koeffizienten_Vektor, Pumpe_Koeffizienten_Vektor)
    7. Dim n_Rohr As Long ' Anzahl der Elemente der Felder
    8. Dim n_Pumpe As Long ' Anzahl der Elemente der Felder
    9. ...
    10. Dim PoKoeff_Rohr() As Double
    11. Dim PoKoeff_Pumpe() As Double
    12. Dim V_Strom As Double
    13. Dim Vorhanden As Boolean
    14. ...
    15. n_Rohr = Rohrleitung_Koeffizienten_Vektor.Rows.Count
    16. n_Pumpe = Pumpe_Koeffizienten_Vektor.Rows.Count
    17. ...
    18. ReDim PoKoeff_Pumpe(1 To n_Pumpe)
    19. ReDim PoKoeff_Rohr(1 To n_Rohr)
    20. ' Koeffizienten_Vektor in einen Delphi-kompatiblen Vektor umwandeln:
    21. ...
    22. Vorhanden = BePu(PoKoeff_Rohr(1), n_Rohr, PoKoeff_Pumpe(1), n_Pumpe, V_Strom)
    23. If Vorhanden Then
    24. Betriebspunkt = V_Strom
    25. Else
    26. Betriebspunkt = "NV"
    27. End If
    28. End Function

    Diese Vorgehensweise habe ich in hunderten anderen VBA-Schnittstellen, welche ohne Probleme funktionieren. Nur das hier scheint richtig verhext zu sein. Die Anweisung in der Zeile

    Quellcode

    1. Vorhanden = BePu(PoKoeff_Rohr(1), n_Rohr, PoKoeff_Pumpe(1), n_Pumpe, V_Strom)

    liefert für Vorhanden = Wahr und V_Strom den korrekten Zahlenwert (z. B. 70,074071...), den ich im Debugger sehen kann. Das Programm arbeitet danach folgende Zeile(n) ab:

    Quellcode

    1. ...
    2. Betriebspunkt = V_Strom

    und verabschiedet sich mit #WERT! in der Zelle der Tabelle, ABER wenn ich das Programm im Debugger schrittweise ablaufen lasse, läuft das Programm manchmal auch regulär weiter über die Anweisungszeilen

    Quellcode

    1. ...
    2. Betriebspunkt = V_Strom
    3. End If
    4. End Function

    und steht ab und zu doch der korrekte Zahlenwert in der Zelle. Nach Speichern, Schließen und erneutem Öffnen der Excel-Arbeitsmappe steht wieder #WERT! in der Zelle und das Spiel beginnt aufs Neue.

    Was mache ich falsch? ?( Irgendetwas habe ich bestimmt übersehen!

    Leider sehe ich den Balken im eigenen Auge nicht. :( Kann mir jemand bitte helfen?
    Vielen Dank für Eure Tipps und Hinweise im Voraus!

    Viele Grüße

    Andreas
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius

    Dieser Beitrag wurde bereits 11 mal editiert, zuletzt von „Andreas_500“ ()

    Meine einzige Idee: Es ist nicht der VBA-Code, sondern die Zelle ist einfach nicht so formatiert, wie es für den Wert nötig wäre. Hat diese eine Formatierung? Dürfte ja eigentlich nicht, weil manchmal der String "NV" reingeschrieben werden soll/kann.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Leider hilft ein Umformatieren der Zelle nicht weiter. Ich hatte auch schon den Windows Defender verdächtigt, aber daran hat es auch nicht gelegen.
    Bin ziemlich ratlos. ?(
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius

    Andreas_500 schrieb:

    Private Declare Function BePu Lib "ChemWings.Flow.dll" _
    (ByRef Rohrleitung_Polynom_Koef_Vektor#, ByVal Anzahl_Werte_Rohr&, ByRef Pumpe_Polynom_Koef_Vektor#, ByVal Anzahl_Werte_Pumpe&, ByRef V_Strom_Betriebspunkt#) As Boolean

    Die vielen ByRef machen mich stutzig.
    Welche der Parameter geben tatsächlich einen Wert zurück?
    Wenn da im Hintergrund etwas asynchron abläuft, wird da womöglich ein Wert verändert, nachdem die Funktion returned ist.

    Auch die Deklaration mit impliziten Datentypen ist ungewöhnlich, das kann Unterschiede in 32/64-Bit-Implementierungen ergeben.
    Gibt's da eine Doku mit expliziten Deklarationen?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hallo,
    Der einzige Rückgabewert ist:

    Quellcode

    1. V_Strom_Betriebspunkt As Double

    Rohrleitung_Polynom_Koef_Vektor und Pumpe_Polynom_Koef_Vektor sind zwei Input-Vektoren (Array of Double). Array-Parameter verlangen nach meinem Kenntnisstand immer nach ByRef, daher diese Deklaration.

    Mein Excel 2019 ist eine 32-Bit-Anwendung, ebenso die DLL. Sie laufen unter Windows 10 (64-Bit).

    Was meinst Du konkret mit „Deklaration mit impliziten Datentypen ist ungewöhnlich …“ ?

    Den Funktionstype von

    Quellcode

    1. Function Betriebspunkt(Rohrleitung_Koeffizienten_Vektor, Pumpe_Koeffizienten_Vektor)

    habe ich bewußt als Variant gewählt, weil bei Fehleingaben in den Vektoren an mehreren Stellen Textzuweisungen erfolgen können. Das hätte in der Delphi-DLL zwar wesentlich einfacher handhaben können, aber weil derartige Funktionen in einer Excel-Arbeitsmappe an zig Stellen vorkommen, wollte ich nicht, daß beim Öffnen der Excel-Arbeitsmappe mit unzulässigen Eingabewerten zuerst x Fehlermeldungen (Messageboxen) quittiert werden müssen.

    Das Fehlverhalten tritt allerdings auch dann auf, wenn ich den Funktionstype auf Double ändere.

    Danke & Grüße
    Andreas
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius
    Habe soeben folgende Beobachtung gemacht: Wenn ich die Funktion mit dem Debugger mit <F5>laufen lasse:

    Quellcode

    1. ...
    2. Vorhanden = BePu(PoKoeff_Rohr(1), n_Rohr, PoKoeff_Pumpe(1), n_Pumpe, V_Strom)
    3. If Vorhanden Then
    4. Betriebspunkt = V_Strom
    5. Else
    6. Betriebspunkt = "NV"
    7. End If
    8. End Function

    und den Breakpoint in der Zeile

    Quellcode

    1. Vorhanden = BePu(PoKoeff_Rohr(1), n_Rohr, PoKoeff_Pumpe(1), n_Pumpe, V_Strom)

    setze, kommt es immer zur Fehlermeldung.

    Ist der Breakpoint hingegen NUR in der Zeile

    Quellcode

    1. If Vorhanden Then

    gibt es keine Fehlermeldung und es steht das korrekte Ergebnis in der Zelle.

    Allerdings ist alles wieder futsch, wenn ich die Excel-Arbeitsmappe neu öffne. :(
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius

    Andreas_500 schrieb:

    Rohrleitung_Polynom_Koef_Vektor und Pumpe_Polynom_Koef_Vektor sind zwei Input-Vektoren (Array of Double)
    Wenn Deine (ist doch Deine, oder?) Delphi-DLL-Funktion Double-Arrays erwartet, warum übergibst Du je einen einzelnen Double-Wert?

    Visual Basic-Quellcode

    1. Private Declare Function BePu Lib "ChemWings.Flow.dll" _
    2. (ByRef Rohrleitung_Polynom_Koef_Vektor#, ByVal Anzahl_Werte_Rohr&, ByRef Pumpe_Polynom_Koef_Vektor#, ByVal Anzahl_Werte_Pumpe&, ByRef V_Strom_Betriebspunkt#) As Boolean
    3. Dim PoKoeff_Rohr() As Double
    4. Dim PoKoeff_Pumpe() As Double
    5. '…
    6. BePu(PoKoeff_Rohr(1), n_Rohr, PoKoeff_Pumpe(1), n_Pumpe, V_Strom)

    Ein einzelner Double-Wert kann normalerweise nicht implizit in ein Double-Array umgewandelt werden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ja es ist meine Delphi-DLL.
    Die Übergabe von Vektoren (Arrays) von VBA nach Delphi (= zwei total verschiedene Welten) geht leider nur etwas umständlich:
    Ich muß in VBA das erste Element des Vektors und die Anzahl der Elemente im Vektor als Parameter übermitteln. Ein Delphi-Vektor enthält neben dem eigentlichen Inhalt auch noch Infos über die Länge etc. Und das kann ich in VBA leider anders nicht nachbilden.

    Darum braucht ein Vektor immer ByRef, weil dadurch eigentlich die Speicheradresse des ersten Elementes übermittelt wird.
    VBA stellt den Usern leider keine Pointer und Adressen-Funktionen zur Verfügung...
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Andreas_500“ ()

    Ok, wenn sichergestellt ist, dass das so mit der Datenübergabe sicher funktioniert, dann ist das erstmal gegessen.
    Kannst Du eine Kopie der Funktion in der Delphi-DLL erstellen, die Dir angibt, welcher Wert denn das Problem darstellt? In .NET könnte man zwar einfach alle Fehlerbehandlung ausschalten, das Programm starten und durch die DLL-Quellenangabe und deren Zusatzdateien schauen, an welcher Stelle es in der DLL kracht, aber durch die externe DLL müsstest Du wohl eher mehr Prüffunktionscode einbauen, um die Parameter zu testen. Vielleicht könntest Du die Abarbeitung der Funktion loggen und sehen, in welcher DLL-Zeile es zum Fehler kommt.
    Das mit der impliziten Typangabe, was petaod (wohl) meinte:

    Visual Basic-Quellcode

    1. Private Declare Function BePu Lib "ChemWings.Flow.dll" _
    2. (ByRef Rohrleitung_Polynom_Koef_Vektor As Double, ByVal Anzahl_Werte_Rohr As Long, ByRef Pumpe_Polynom_Koef_Vektor As Double, ByVal Anzahl_Werte_Pumpe As Long, ByRef V_Strom_Betriebspunkt As Double) As Boolean

    Oder vielleicht doch Integer statt Long?

    ##########

    Ehm, vielleicht war es nicht Absicht von Dir, aber wenn die Moderation Deinen Post bearbeitet, weil Rot der Moderation vorbehalten ist, dann ist es nicht gut, wenn Du die Farbe Rot durch Postbearbeitung wieder einfügst. Bitte die Farbe beim Text

    Andreas_500 schrieb:

    Ja es ist meine Delphi-DLL.
    in etwas anderes ändern.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo,
    zunächst die einfachere Antwort: Auf 32-Bit-Ebene sind Delphi’s Integer und VBA’s Long kompatibel.
    Für den Rest brauch ich etwas Zeit.
    Danke & Grüße
    Andreas

    PS:
    Die Farben & sonstige Formatierungswerkzeuge sind in meinem Editor leider deaktiviert und ich kann sie (noch) nicht benutzen.
    Rot habe ich oben spontan per Hand eingefügt. Sorry
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius
    Vom Delphi-Debugger aus kann ich die Excel-Anwendung aufrufen und auch schrittweise laufen lassen. Das habe ich mir zum x-ten Male angeschaut und jeden Schritt und jeden Zahlenwert analysiert.
    Ich kann dabei sehen, wie alle Daten von Excel korrekt in der ChemWings.Flow.dll ankommen, dort alle Berechnungen korrekt ausgeführt werden und das Ergebnis zurück nach Excel geht. In der Variablen V_Strom steht stets das korrekte Ergebnis.

    Zum Crash kommt es immer dann, wenn nach der DLL-Benutzung mit V_Strom irgendetwas gemacht wird, z. B. selbst so:

    Visual Basic-Quellcode

    1. V_Strom = V_Strom + 0.0

    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Andreas_500“ ()

    Was passiert, wenn Du nach dem DLL-Funktionsaufruf sowas machst:

    Visual Basic-Quellcode

    1. Dim Safe_V_Strom As Long
    2. Safe_V_Strom = V_Strom
    3. Safe_V_Strom = Safe_V_Strom + 1

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Moment bitte...
    Anstelle von 70,07 etc steht 71 in der Zelle.

    PS.
    Aber beim erneuten Öffnen der Datei steht immer noch #WERT! da

    Ich werde eine Testanwendung erstellen und die kompletten Dateien im Anhang posten.
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Andreas_500“ ()

    Im Anhang befindet sich eine Testanwendung.
    Danke für Eure Hilfe!

    Grüße
    Andreas

    PS:
    Lösung: --> Sollwert = 70,074071998727843000
    Dateien
    • Betriebspunkt.zip

      (915,42 kB, 13 mal heruntergeladen, zuletzt: )
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius
    Was mich verwundert: Selbst wenn man Vorhanden = BePu(PoKoeff_Rohr(1), 1, PoKoeff_Pumpe(1), 1, V_Strom) oder gar Vorhanden = BePu(PoKoeff_Rohr(1), 0, PoKoeff_Pumpe(1), 0, V_Strom) verwendet, funktioniert der Aufruf nicht und die Abarbeitung der Excelfunktion bricht an dieser Stelle ab.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Beim Aufruf der DLL-Funktion mit Vorhanden = BePu(PoKoeff_Rohr(1), 0, PoKoeff_Pumpe(1), 0, V_Strom)
    und / oder Vorhanden = BePu(PoKoeff_Rohr(1), 1, PoKoeff_Pumpe(1), 1, V_Strom)
    erhalte ich korrekterweise eine Fehlermeldung aus der DLL (s. Anhang):
    Fehler!
    Datenfehler: Länge von Polynom_Koef_Vektor muß im Bereich 1 ... 21 liegen!

    und im Überwachungsfenster für die Variable V_Strom:

    V_Strom = 1,#QNAN (= Not a Number), was auch korrekt ist.
    Die Ergebnisse aus der DLL kommen also in Excel an... ?(
    Dateien
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius
    Bilder kannst Du forenintern über [+ Erweiterte Antwort] -> _|Dateianhänge|_ -> [Hochladen] posten.

    Bei mir kommt da gar keine Fehlermeldung. Das Makro läuft bis zur DLL-Aufrufzeile durch, bricht dann ab und Excel zeigt im Sheet weiterhin/erneut #Wert! an.
    Ich kann da wohl nicht weiterhelfen, weil ich das Szenario nicht nachstellen kann.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Excel findet eine DLL (leider) nur wenn:

    a): diese im Verzeichnis C:\Windows\ liegt, oder
    b): der komplette Pfad angegeben ist.

    Bitte in

    Private Declare Function BePu Lib "Kompletter Pfad\ChemWings.Tools.dll" _

    den Pfad ergänzen.
    Grüße, Andreas

    PS:
    Die Fehlermeldung der DLL sollte korrekt heißen: Datenfehler: Länge von Polynom_Koef_Vektor muß im Bereich 2 ... 21 liegen!
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Andreas_500“ ()

    Leider unverändert. Der Pfad ist vollständig und korrekt angegeben, aber Excel verhält sich unverändert. Habe auch versucht, die DLL mal per VS dynamisch einzubinden, aber da heißt es nur, dass das Modul nicht gefunden wurde.
    Hat die DLL weitere, eigene Abhängigkeiten?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hat die DLL weitere, eigene Abhängigkeiten?

    Nein, alles ist in der einen DLL komplett drin. ?(

    PS:
    Habe noch eine Idee: Vielleicht muß die DLL im WinExplorer als "vertrauenswürdig" markiert werden, weil sie ja von einem fremden Computer stammt.

    Im Fenster "Eigenschaften" --> "Allgemein" ganz unten: Sicherheit: --> zulassen
    Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
    John C. Cornelius

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Andreas_500“ ()