none
Berechnete Felder werden nicht berechnet

    Frage

  • Hallo liebes Forum,

    ich habe ein kleines Problem: Wir entwickeln seit einigen Jahren mit Access und haben in manchen Formularen Controls, deren ControlSource auf eine VBA-Funktion geht.

    Zum Beispiel in einem Endlosformular ist eine Checkbox mit ControlSource "=hasDocument([Nr])" (Nr ist ebenfalls eine Textbox im gleichen Formular).

    Die Funktion hasDocument() sieht so aus:

    Function hasDocument(nr As Variant) As Boolean
        On Error Resume Next
       
        If IsNull(nr) Then
            ' pass
        ElseIf err <> 0 Then
            ' pass
        Else
            hasDocument = DExists("ID", "Kurztexte", "Aufwendungs_Nr=" & nr)
        End If
    End Function

    Unter normalen Umständen funktioniert der Code. Die Funktion wird aufgerufen und das Häckchen wird entweder angezeigt, oder nicht. Manchmal kommen die Rechner allerdings in einen Zustand, wo das nicht funktioniert. Keine Häckchen warden mehr angezeigt. Wenn man einen Haltepunkt in die Funktion setzt, wird der Code nicht unterbrochen. Erst wenn das Control den Focus erhält wir die Funktion ausgeführt und das Häckchen wird angezeigt.

    Andere Formulare mit anderen Funktionen sind ebenfalls betroffen. Berichte allerdings nicht.

    Bisher hat immer ein Neustart des Rechners geholfen, da wir aber die Accesslösung auch auf unseren Terminalserver haben, ist ein Neustart dort nicht möglich.

    Woran liegt das?



    • Bearbeitet rocom GmbH Mittwoch, 9. April 2014 15:19 Rechtschreibung, Titel klarer formuliert
    Mittwoch, 9. April 2014 15:12

Alle Antworten

  • Am 09.04.2014 schrieb Wolfgang86:

    Zum Beispiel in einem Endlosformular ist eine Checkbox mit ControlSource "=hasDocument([Nr])" (Nr ist ebenfalls eine Textbox im gleichen Formular).

    Was spricht gegen die Bedingte Formatierung? Ist möglicherweise besser
    geeignet.

    Die Funktion hasDocument() sieht so aus:

    Function hasDocument(nr As Variant) As Boolean
        On Error Resume Next

    Eine Fehlerbehandlung <> On Error Resume Next ist das mindeste.

    Bisher hat immer ein Neustart des Rechners geholfen, da wir aber die Accesslösung auch auf unseren Terminalserver haben, ist ein Neustart dort nicht möglich.

    Hat jeder Benutzer sein eigenes Frontend oder liegt das FE im Netzwerk
    für alle zentral? Hast Du das FE schon mit /decompile bearbeitet?
    http://www.donkarl.com?FAQ1.23
    Zuerst /compact, dann /decompile und nochmal /compact. Sicherung
    vorher machen!


    Servus
    Winfried

    Gruppenrichtlinien
    WSUS Package Publisher
    HowTos zum WSUS Package Publisher
    NNTP-Bridge für MS-Foren

    Mittwoch, 9. April 2014 16:36
  • Vielen Dank für deine Antwort! Ich bin wirklich mit meinem Latein am Ende.

    Bedingte Formatierung würde in der Maske natürlich gehen. Historisch bedingt war die Anzeige ob ein Dokument hinterlegt ist leider immer durch ein Häkchen angezeigt. Daher würde ich das gerne nicht ändern. Es betrifft aber auch anderee Felder, in denen VBA Funktionen hinterlegt sind. Z.b. wenn Zahlen speziell gerundet werden müssen, oder ähnliches.

    Eine Fehlerbehandlung in allen Funktionen ist natürlich sinnvoll. Das ist schlechter Code, da kann man nicht dikutieren. Darum geht es mir jedoch nicht. Es tratt beim Debuggen kein Fehler innerhalb der Funktion auf. Wenn ich einen Haltepunkt beim "On Error Resume Next" setze, halt er die Funktion nicht an. Ein Debug.Print ganz am Anfang der Funktion wird nicht erreicht.

    Wir verbinden uns per RDP auf den Server und starten dort lokal die Datenbank. Jeder hat natürlich sein eigenes Windows Profil und eine eigene Access Datenbank. Backend ist SQL Server 2005, in einer anderen Installation die das Problem vorhanden ist haben wir eine SQL Server 2008 R2.

    Die Datenbank wird für jede Version über einen MsBuild-script aus unserem Repository erstellt was ein compile, decompile und erneutes compile beinhaltet. Wenn ich die fertig gebaute Datenbank nochmal nehme, compile->decompile->compile ausführe ändert sich das Verhalten nicht. Trotzdem guter Hinweis, vielen Dank!

    Da hast du mich auf die Idee gebracht eine neue Testdatenbank mit berechneten Feldern anzulegen. Leider tritt auch da das Problem auf..

    Auf meinem Rechner sieht die Testmaske so aus:

    Die gleiche Testmaske auf dem Server:

    Wie gehabt wenn ich in die Textboxes nach "hasDocument(Text0)" bzw "hasDocument2(Text0)" klicke, wird der VB Code der Textbox die den Focus hat ausgeführt. Der Text dieser Textbox wird dann angezeigt. Der Text der anderen ist jedoch immer noch nicht sichtbar.


    • Bearbeitet rocom GmbH Donnerstag, 10. April 2014 08:38 Fehlerverhalten genauer beschrieben
    Donnerstag, 10. April 2014 08:36
  • Am 10.04.2014 schrieb Wolfgang86:

    Vielen Dank für deine Antwort! Ich bin wirklich mit meinem Latein am Ende.

    Bedingte Formatierung würde in der Maske natürlich gehen. Historisch bedingt

    Probier es an einem Formular aus. Wenn das hilft kannst Du umstellen.

    Es tratt beim Debuggen kein Fehler innerhalb der Funktion auf. Wenn ich einen Haltepunkt beim "On Error Resume Next" setze, halt er die Funktion nicht an. Ein Debug.Print ganz am Anfang der Funktion wird nicht erreicht.

    Hast Du schon eine neue leere DB erzeugt und alles importiert? Die
    dann ausprobieren.


    Servus
    Winfried

    Gruppenrichtlinien
    WSUS Package Publisher
    HowTos zum WSUS Package Publisher
    NNTP-Bridge für MS-Foren

    Freitag, 11. April 2014 05:04
  • Hallo Winfried,

    die Bedingte Formatierung würde in diesem Fall natürlich funktionieren. Das verunsichert mir aber zu sehr die Anwender. Außerdem können so nicht alle Fälle abgedecken werden. Was ist mit Textfeldern in denen berechnete Zahlen stehen? Das ist mit bedingter Formatierung nicht möglich.

    Eine neue leere DB erzeugen und importieren hab ich schon probiert, verändert das Verhalten leider nicht. Ich denke dass die Datenbank in Ordnung ist, da ich den Fehler auch in der Testdatenbank bekomme. Dort sind 2 Formulare, 1 Marko und 1 Modul vorhanden. Keine zusätzlichen Verweise auf eine externe Bibliotheken.

    Wir haben auch schon probiert die Datenbank auf einem anderen Rechner zu erzeugen. Leider keine Änderung des Verhaltens. Auch wenn ich ein anderes Format verwende (accdb, accde, mdb, mde) ändert sich das Verhalten nicht.

    Freitag, 11. April 2014 08:48
  • Hallo Wolfgang

    Die Funktion DExists() gibt es im Standard Funktionsumfang nicht. Ich denke, das ist eine selber geschriebene Funktion, korrekt? Es könnte sein, dass damit Datenbank Instanzen hängen bleiben und nicht mehr freigegeben werden. In diesem Fall wäre dann evtl. auch MSAccess auch nach geschlossener Anwendung immer noch im Taskmanager sichtbar.

    Wieso verwendest Du statt dessen nicht die eingebaute Funktion DCount(), welche es ja gibt? Allenfalls Performance Bedenken?

    Dein Code (nur die betroffene Zeile) würde dann so aussehen:

    hasDocument = DCount("*", "Kurztexte", "Aufwendungs_Nr=" & Nz(nr))

    Ich habe da auch ein Nz() um das Feld [nr] herum gemacht, da nr ja evtl. NULL sein könnte (neuer Datensatz). In diesem Fall würde sonst DCount() einen Fehler auslösen, weil die WHERE Bedingung unvollständig ist.

    Ansonsten zeige mal den Code von DExists() her.

    Gruss

    Henry
    Freitag, 11. April 2014 09:42
  • Hallo Henry,

    vielen Dank für den Hinweis. DExists() ist eine Eingentwicklung gerne hier den Code dazu:

    Function DExists(Expr As String, Domain As String, Optional Criteria) As Boolean
        DExists = Not IsNull(DLookup(Expr, Domain, Criteria))
    End Function
    
    Function DLookup(Expr As String, Domain As String, Optional Criteria, Optional OrderBy, Optional par_db As DAO.Database)
        Dim db As DAO.Database
        Dim rs As DAO.Recordset
        Dim strSql As String
        
        Dim eNummer As Long
        Dim eSource As String
        Dim eDescription As String
        
        On Error GoTo DL_Error
        
        strSql = buildSelect("SELECT TOP 1 " & Expr, Domain, Criteria, OrderBy)
        
        If par_db Is Nothing Then Set db = Currentdb() Else Set db = par_db
        Set rs = db.OpenRecordset(strSql, dbOpenForwardOnly)
        
        If rs.RecordCount = 0 Then
            DLookup = Null
        Else
            DLookup = rs(0)
        End If
        
    DL_Exit:
        On Error Resume Next
        rs.Close
        Set rs = Nothing
        Set db = Nothing
        err = 0
        If eNummer <> 0 Then On Error GoTo 0: err.Raise eNummer, eSource, eDescription
        Exit Function
        
    DL_Error:
        eNummer = err.Number
        eSource = err.Source
        eDescription = err.Description
        Resume DL_Exit
    
    End Function
    

    Aber wie gesagt kommt er gar nicht in die Funktion rein. Kein einziges Mal.

    Ein einfacheres Beispiel ist vielleicht die Testdatenbank, auf die mich Winfried gebracht hat. Da taucht der Fehler ja auch auf und die Funktionen sind sehr sehr einfach gestrickt:

    Function hasDocument(Nr As Variant) As String
        hasDocument = "Dokument"
    End Function
    
    Function hasDocument2(Nr As Variant) As String
        hasDocument2 = "Dokument2"
    End Function
    
    Function hasDocument3(Nr As Variant) As String
        hasDocument3 = "Dokument3"
    End Function
    
    Function hasDocument4() As String
        hasDocument4 = "Dokument4"
    End Function
    
    Einen Zombieprozess von MSAccess gibt es nicht. Ich habe jetzt mal alle Benutzer vom Server

    abgemeldet, inkl. den Admin. Dann meinen User angemeldet, nochmal im Taskmanager geschaut: kein MSACCESS.EXE, mein User als einzigster auf dem Server. Der Fehler tritt dennoch noch auf.

    Danke für den Vorschlag mit DCount! Diese DExists hat nur ein wenig Performancevorteil, aber mittlerweile will ich nur dass es überall geht. Wenn ich deinen Vorschlag 1:1 kopiere geht es zwar auf meinem Rechner, auf dem Server aber wieder nicht. Aber wie gesagt, diese simplen Testfunktionen in der Testdatenbank gehen auch schon nicht. Irgendetwas hindert Ihn daran den VBA-Code auszuführen.

    Beste Grüße

    Wolfgang

    Freitag, 11. April 2014 11:04
  • Merkwürdig. Auf dem Server ist die gleiche Anwendung drauf? Ist es eine MDE? Falls nicht, ändern. Sicherheitshalber sollten Benutzer immer nur mit MDEs arbeiten.

    Einen Decompile hast Du bereits gemacht?

    Könnte auch sein, dass die Prozeduren nicht richtig verlinkt sind.  In diesem Fall mal eine Replace in der VDE im ganzen Projekt machen:

    'Private Function' -> 'private Function'

    Das gleiche dann mit den Subs.

    Damit werden alle Verknüpfungen von Ereignisprozeduren wieder hergestellt, die bei Copy Paste von Code verloren gehen können.

    Gruss Henry

    Montag, 14. April 2014 04:28
  • Hallo!

    Du schreibst: "Ein Debug.Print ganz am Anfang der Funktion wird nicht erreicht."

    Könnte es sein, dass die Ausführung von VBA-Funktionen gesperrt ist?
    .. Also so, als ob die Anwendung nicht in einem "sicheren Speicherort" lieg
    t.

    Ist [Nr] nur ein Steuerelementname oder ist das eventuell auch der Name eines Datefeldes in der Datenherkunft des Formulars?
    => vielleicht hilft es, wenn das Textfeld von [Nr] auf [txtNr] umbenennst.
    Anm.: Ich hatte auch einmal Probleme beim Aktualisieren der Anzeige (mit Access 2007) in berechneten Feldern. Lösung (Problemumgehung) war die Berechnung nicht mit den Datenfeldern sondern mit Steuerelementen, welche an die Datenfelder gebunden waren, durchzuführen.

    mfg
    Josef


    Code-Bibliothek für Access-Entwickler
    AccUnit - Testen von Access-Anwendungen
    Virtueller Access-Stammtisch




    Montag, 14. April 2014 12:27
  • Am 11.04.2014 schrieb Wolfgang86:

    die Bedingte Formatierung würde in diesem Fall natürlich funktionieren. Das verunsichert mir aber zu sehr die Anwender.

    Weshalb sollte das die Anwender verunsichern? Die kriegen doch gar
    nicht mit was dahinte passiert, oder etwa doch?

    Außerdem können so nicht alle Fälle abgedecken werden. Was ist mit Textfeldern in denen berechnete Zahlen stehen? Das ist mit bedingter Formatierung nicht möglich.

    Du wirst wohl oder übel den Verursacher finden müssen.

    Eine neue leere DB erzeugen und importieren hab ich schon probiert, verändert das Verhalten leider nicht. Ich denke dass die Datenbank in Ordnung ist, da ich den Fehler auch in der Testdatenbank bekomme. Dort sind 2 Formulare, 1 Marko und 1 Modul vorhanden. Keine zusätzlichen Verweise auf eine externe Bibliotheken.

    Wir haben auch schon probiert die Datenbank auf einem anderen Rechner zu erzeugen. Leider keine Änderung des Verhaltens. Auch wenn ich ein anderes Format verwende (accdb, accde, mdb, mde) ändert sich das Verhalten nicht.

    Welcher AV-Scanner ist installiert? Könnt ihr den rückstandsfrei
    deinstallieren? Welche Einstellungen sind in Access bezüglich VBA und
    Maktor festgelegt? Liegen die Frontends in den Vertrauenswürdigen
    Speicherorten?


    Servus
    Winfried

    Gruppenrichtlinien
    WSUS Package Publisher
    HowTos zum WSUS Package Publisher
    NNTP-Bridge für MS-Foren

    Montag, 14. April 2014 18:40
  • Guter Hinweis Josef. Das würde erklären, wieso es auf der lokalen Maschine mit DCount() läuft, nicht aber auf dem Terminal Server. Wenn Makros ohne Hinweis auf dem Server abgewürgt werden, dann würde das das unterschiedliche Verhalten erklären.

    Gruss

    Henry

    Dienstag, 15. April 2014 06:36
  • Hallo Wolfgang

    Was mir nicht gefällt ist dass die eigene Funktion DLookUp() genau so heisst wie die eingebaute Access Funktion. Ich würde die eigene Funktion mal anders benennen (zB. fDLookUpSort() ) das könnte nämlich auch einen Konflikt geben.

    Gruss Markus

    Mittwoch, 16. April 2014 08:44
  • Hallo miteinander,

    vielen Dank für die Hinweise!

    * Auf dem Server läuft normalerweise die MDE. Als der Fehler das erste Mal auftratt hatten wir die MDB installiert, welche dasselbe Verhalten an den Tag legte. Die Dateiformate ACCDB und ACCDE verhalten sich ebenfalls so.

    * Das Replace haben wir zum Neuverlinken der Prozeduren gerade mit der Testdatenbank probiert. Wir haben "Private Function", "Private Sub", "Public Sub" und "Public Function" ersetzt. Das Verhalten ändert sich nicht. :(

    * Nr ist tatsächlich sowohl Datenbankfeld als auch Textbox im Formular. Allerdings tritt der Fehler auch in der Testdatenbank mit "=hasDokument4()" auf.

    * Als Antivirenprogramm verwenden wir GData. Den kann ich allerdings nicht einfach deinstallieren ohne einen Serverneustart. Nach dem Neustart tritt der Fehler ja dann erstmal nicht mehr auf..

    * Die Testdatenbank befindet sich in den vertrauenswürdigen Speicherorten, VBA-Funktionen sind nicht gesperrt.

    Was uns gerade noch aufgefallen ist, funktionieren die Funktionen die der Bibliothek VBA z.b. Val oder CBool! Funktionen in der Bibliothek Access und im Projekt selbst nicht.

    sorry für das viele vertippen im gif, ich bin die englische Tastatur gewohnt..

    Code des Formulars:

    Option Compare Database
    Option Explicit
    
    Private Sub Befehl18_Click()
        Text14.ControlSource = "=" & Text12
    End Sub

    Gruß Wolfgang

    Dienstag, 22. April 2014 13:54
  • Hallo Markus,

    vielen Dank für den Hinweis. Du hast natürlich Recht. Das Problem tritt auch in der Testdatenbank mit den Funktionen hasDocument, hasDocument2, hasDocument3, hasDocument4, NZ und BuildCriteria auf.

    In der Testdatenbank ist keine selbstentwickelte Funktion namens DLookup vorhanden.

    Gruß Wolfgang

    Dienstag, 22. April 2014 13:58
  • In diesem Fall ist es evtl. die Access FAQ 7.1

    Kontrolliere mal die Verweise und lösche alle raus, die Du nicht benötigst. Wenn immer möglich, wechsle auf Late Binding (für alles ausser die, die es wirklich braucht). In diesem Fall passiert nichts, wenn mal eine DLL nicht gefunden wird, solange der Code nicht ausgeführt wird.

    Gruss

    Henry

    Mittwoch, 23. April 2014 04:21
  • Hallo Henry,

    in der Testdatenbank ist nur der Verweis auf VBA und Access vorhanden. Die beiden kann ich nicht verändern.

    Den Verweis auf die DAO hab ich auch mal entfernt, da ich die nicht verwende. Mit und ohne DAO verhält es sich identisch

    Externe Funktionen per "Declare Function" werden nicht verwendet.

    Die Access Installation über das Setup zu reparieren hat auch nichts gebracht. Ebenso das deinstallieren und erneute Installieren von Access bringt nichts.

    Gruß Wolfgang

    Mittwoch, 23. April 2014 06:54
  • Hallo Wolfgang

    Das kann nicht sein. Du musst entweder DAO oder ADO drin haben, um auf die Datenbank zuzugreifen. Diese darfst Du nicht weglöschen, sonst läuft nicht mehr viel.

    Mach' mal die auf DAO wieder rein und versuche es erneut. Evtl. wird das dann repariert.

    Welche Access Version setzt Du übrigens ein? 2010? In diesem Fall wäre wohl ein Verweis auf die "Microsoft Office 14.0 Access Database Engine Object Library" die richtige (wenn Du ACCDBs verwendest) statt DAO korrekt.

    Details siehe FAQ 7.1, Link habe ich bereits geschickt.

    Gruss

    Henry



    Mittwoch, 23. April 2014 09:05
  • Hallo Henry,

    in der Testdatenbank wird nicht auf die Datenbank zugegriffen. Daher konnte der Verweis auf die "Microsoft Office 14.0 Access Database Engine Object Library" entfernt werden. Die ACCDB lässt sich weiterhin kompilieren und auf meinem Rechner (Win 7 32 Bit/Access 2010 32 Bit) tritt der Fehler nicht auf.

    Auf dem Server jedoch (Win Server 2008 R2 64 Bit/Access 2010 32 Bit) tritt der Fehler mit/ohne Verweis auf die "Microsoft Office 14.0 Access Database Engine Object Library" auf.

    Das Anfangs erwähnte DLookup ist in einem anderen, größerem Programm zu finden. Nach deiner ersten Antwort hatte ich eine neue simple Testdatenbank angelegt. Dort tritt der Fehler auch auf, seitdem debugge ich dort. Ich bin mir sicher wenn dort der Fehler gefunden wird, kann das auf das größere Programm ebenfalls angewendet werden.

    Vielen Dank für den Link auf FAQ 7.1. Bei den beiden Verweisen steht IsBroken auf False. Die in FAQ 7.1 verlinkte Problemlösung auf der MSDN zeigt keine Besserung.

    Der Server und auch die anderen Rechner auf dem das Problem auftritt sind 64Bit-Systeme, mein lokaler Rechner ein 32 Bit Windows 7. Auch der Rechner der normalerweise die MDEs erstellt ist ein 32Bit-System.. Also jede getestete MDB/MDE/ACCDB/ACCDE wurde mit einem 32Bit System erstellt und auf einem 64Bit System gab es dann den Fehler.. Kann es damit irgendwas zu tun haben?

    Mittwoch, 23. April 2014 10:49
  • Am 23.04.2014 schrieb Wolfgang86:

    in der Testdatenbank wird nicht auf die Datenbank zugegriffen. Daher konnte der Verweis auf die "Microsoft Office 14.0 Access Database Engine Object Library" entfernt werden. Die ACCDB lässt sich weiterhin kompilieren und auf meinem Rechner (Win 7 32 Bit/Access 2010 32 Bit) tritt der Fehler nicht auf.

    Kannst Du die abgespeckte Testdatenbank zur Verfügung stellen? Auf
    dein Skydrive uploaden und den Link hier posten. Wie das geht, steht
    in diesem Artikel:
    http://answers.microsoft.com/de-de/windows/forum/windows_7-networking/wie-nutze-ich-skydrive/af6c55f1-0e82-460e-babb-794ff26e5698


    Servus
    Winfried

    Gruppenrichtlinien
    WSUS Package Publisher
    HowTos zum WSUS Package Publisher
    NNTP-Bridge für MS-Foren

    Mittwoch, 23. April 2014 16:28
  • Hallo Wolfgang

    ob Windows 32 oder 64 bit ist, spielt eigentlich keine Rolle. Was Du aber verschweigst ist, welche Version von Office installiert ist. Achte darauf, dass die 32-bit Version installiert ist. Diese läuft dann in der WOW64 (die 32-bit Umgebung von Windows 64 bit). Dies funktioniert eigentlich problemlos.

    Auch solltest Du mal schreiben, welche Version von Office überhaupt installiert ist. Office 2013 oder Office 2010? Die stabilere Version ist Office 2010.

    Was war der Grund auf eine ACCDB zu wechseln? Brauchst Du die neuen Features? Du könntest auch weiterhin im alten Format mit einer MDB fahren, das läuft sehr zuverlässig.

    Gruss

    Henry

    Donnerstag, 24. April 2014 03:32
  • Ich habe die Testdatenbank aufs SkyDrive gestellt: http://1drv.ms/1ft98CP

    Verwendete Access Version ist 2010 SP 2 32 Bit. Word, Excel, Powerpoint und Outlook 2003 sind auf dem Server installiert, aber kein Access 2003!

    Der Fehler tritt ebenso in der MDB (und auch MDE, ACCDE, ACCDB) auf. Danke für den Hinweis auf die stabilere MDB, das Problem besteht aber auch dort.

    Gruß

    Wolfgang

    Donnerstag, 24. April 2014 09:41