Hallo, evtl was ganz banales (aber das sind ja meistens die schwierigsten Dinge!):
Ich möchte, wenn ein Formular geöffnet wird einen fortlaufenden Zähler setzen und in einem Textfeld anzeigen. Es handelt sich um das Eröffnungsformular welches über eine Makro automatisch angezeigt wird (AutoExec). Ich dachte an ein neues Tabellenfeld "txtZähler"welches mit dem Formular verknüpft ist. Ist das über eine Public Function möglich dem Textfeld einen Wert zuzuweisen und welches Ereignis im Eigenschaftsdatenblatt müsste ich hier benutzen?
Gruß
Herbert
Hallo,
bei jedem Öffnen des Formulars 1 hochzählen ?
Und was hats Du dann mit dem Zähler vor ?
Hallo Klaus,
ja genauso - d.h. wenn das Eröffnungsformular geöffnet wird sollte der Zähler sich um 1 erhöhen. Mit einem Button wäre das kein Problem - aber wie macht man, dass beim Öffnen eines Formulares der Zähler automatisch erhöht wird?
Es handelt sich hier um ein Formular welches eigentlich von den Mitarbeitern benutzt werden sollte und das Standardformulare (Quittungen, Mahnungen etc.) zum Ausfüllen und Ausdrucken bereit hält. Ich möchte nun wissen wie oft das Formular von den Mitarbeitern genutzt wird (leider gibt es diese Standardformulare immer noch als Wordausgaben - und dort schleichen sich dann beim Ausfüllen auch immer wieder Fehler ein). Mit der Zahl der Aufrufe meines Formulares hätte ich doch mal einen Überblick wie oft es genutzt wird im betrieblichen Ablauf.
Grüße
Herbert
Zitat von: herb54 am November 09, 2018, 15:13:41
Ich möchte nun wissen wie oft das Formular von den Mitarbeitern genutzt wird (leider gibt es diese Standardformulare immer noch als Wordausgaben - und dort schleichen sich dann beim Ausfüllen auch immer wieder Fehler ein). Mit der Zahl der Aufrufe meines Formulares hätte ich doch mal einen Überblick wie oft es genutzt wird im betrieblichen Ablauf.
Das artet zwar schon wieder in Richtung Gefummel aus, aber man könnte im Formularereignis form_load() eine Routine aufrufen, welche irgendwo eine Hilfstabelle inkrementiert, so nach der Art
"UPDATE tblZaehler SET Aufrufe=Aufrufe+1;", vielleicht auch eine Protokollierung mit "INSERT INTO" und Zeitstempel. Statt der Datenbanktabelle könnte man auch in eine Textdatei wegschreiben.
Hallo,
ich würde dazu eine eigene Tabelle anlegen (tblFormAufrufe) darin ein Feld (Aufrufzähler) hochzählen. Das sieht dann so aus:
Private Sub Form_Load()
CurrentDb.Execute "UPDATE tblFormAufrufe SET tblFormAufrufe.AufrufZähler = " _
& " Nz(DMax('Aufrufzähler','tblFormAufrufe'),0)+1", dbFailOnError
End Sub
Den 1. Datensatz mit Zähler 0 musst Du einmalig von Hand anlegen.
Hallo zusammen,
das Ganze funktioniert einwandfrei. Ich musste allerdings den ersten Datensatz auf Zähler = 1 stellen. Allerdings versteh ich die VBA Anweisung nicht so ganz - das muss ich mir mal ganz genau "durchleuchten". Ich denke, da kommt vielleicht noch eine Frage. Auf jeden Fall funktioniert es einwandfrei! Und somit erstmal vieeeelen Dank!
Gruß
Herbert
Hallo Klaus,
sorry, ich kenne DMax nicht, daher hier meine Frage:
Was ist der Unterschied zwischen DomMax und DMax?
DomMax gibt normalerweise den Datensatz zurück der den größten Wert eines Tabellenfeldes für ein Kriterium eines anderen Feldes enthält der gleichen Tabelle zurück mit folgender Syntax:
DOMMAX(Tabellenfeld dessen größter Wert gesucht wird;"Tabelle";"Kriterienfeld")
Bei Textfeldern einfaches Anführungszeichen bei Tabelle und Kriterienfeld
Bei Zahlenfeldern doppeltes Anführungszeichen bei Tabelle und Kriterienfeld
Das kann dann mit DMax nix zu tun haben oder (schon wegen der Anführungszeichen)???
Grüße
Herbert
Hallo,
DMax und DomMax ist exakt das Gleiche.
DomMax ist die eingedeutsche Version der SQL/VBA Funktion DMax.
Innerhalb der deutschen Oberfläche muss auch statt des Kommas das Semikolon verwendet werden.
Hallo Klaus,
super vielen Dank - wieder was gelernt! Und das mit den einfachen Anführungszeichen kommt von den doppelten die schon vor der Klammer " Nz(DMax... stehen???
Gruß
Herbert
Hallo,
wenn innerhalb eines Srings der in die Az (") eingeschlossen wird, noch mal Az vorkommen, so muss das einfache Az (Hochkomma ') verwendet werden, oder es müssen die Az verdoppelt werden, was ich persönlich aber völlig unübersichtlich finde.
Wenn Du z.B. eine Feldzuweisung machen würdest, ist das Az zu verwenden.
Me.Formularfeld = Nz(DMax("Aufrufzähler","tblFormAufrufe"),0)+1
Das & " Nz .... kommt nur von dem Zeilenumbruch der VBA Zeile.
Das kann auch in einer Zeile geschrieben werden, dann sieht das so aus.
CurrentDb.Execute "UPDATE tblFormAufrufe SET tblFormAufrufe.AufrufZähler = Nz(DMax('Aufrufzähler','tblFormAufrufe'),0)+1", dbFailOnError
Dann ist es aber zur breit und es wird unübersichtlich.
Hallo Klaus,
alles klar! Vieeelen Dank für deine Hilfe!!
Grüße
Herbert
Hallo zusammen,
der vorher beschriebene Aufrufzähler hat bisher super funktioniert. Jetzt zeigt mir das Zählerfeld jedoch nur noch "0" an und die Db.Execute wird nicht ausgeführt. dbFailOnError zeigt den Wert 128 an. Woran kann das liegen?
Kann das sein, dass da nur bis zu einem bestimmten Wert hochgezählt wird und dann funktioniert es nicht mehr bzw. wird die Fehlermeldung 128 ausgegeben? Wenn ich das Zählerfeld manuell wieder auf 1 stelle funktioniert der Zähler wieder.
Grüße
Herbert
ZitatdbFailOnError zeigt den Wert 128
Was soll das bedeuten?
Falls Du eine Fehlernummer meinst, einen Fehler 128 kenne ich nicht.
Hallo,
128 ist die Konstante für dbFailOnError und hat mit einem Fehler nichts zu tun.
Man könnte auch schreiben:
.... +1", 128
Das ist das Gleiche.
Hallo Klaus,
was bedeutet denn 128? Wir da nur bis zu einem bestimmten Wert hochgezählt?
Grüße
Herbert
Hallo,
Zitatwas bedeutet denn 128?
habe ich doch geschrieben. Das hat mit einem Fehler nichts zu tun. Das ist die VBA konstante zu dbFailOnError.
Das ist für Dich völlig unwichtig.
.... +1", 128
oder
.... +1", dbFailOnError
Ist beides gleichwertig und muss Dich nicht weiter interessieren.
Der Zusatz sorgt für eine Fehlermeldung wenn die Abfrage zu einem Fehler führt.
Die Ausgabe von 0 ist aber kein Fehler an der Abfrage selbst, sondern, die Abfrage liefert eben 0.
Hallo,
@Klaus
ZitatDen 1. Datensatz mit Zähler 0 musst Du einmalig von Hand anlegen.
Kann man aber auch automatisieren
Private Sub Form_Load()
If Nz(DMax('Aufrufzähler','tblFormAufrufe'),0) = 0 Then
CurrentDb.Execute "INSERT INTO tblFormAufrufe (AufrufZähler) VALUES(0)", 128
Else
CurrentDb.Execute "UPDATE tblFormAufrufe SET AufrufZähler = " _
& " DMax('Aufrufzähler', 'tblFormAufrufe')+1", dbFailOnError
End If
End Sub
@Herbert
128 bzw. dbFailOnError dient dazu, dass überhaupt eine Fehlermeldung ausgegeben wird.
ZitatKann das sein, dass da nur bis zu einem bestimmten Wert hochgezählt
Ja, wenn du das Feld in der Tabelle zu klein gewählt hast. Nimm als Datentyp Zahl/LongInteger.
gruss ekkehard
Hallo Ekkehard,
ich hatte Datentyp Long Integer. Da das Programm auf einem Server liegt mache ich mir jetzt irgendwie Gedanken, ob da jemand versucht hat zu hacken, denn mit dem Zahlenbereich den Long Integer zur Verfügung stellt, hätte ich bei den Aufrufen durch die User nie das Ende von Long Integer erreicht. Schade, dass man da nix einbauen kann, wo ein schnelles Hochzählen durch sehr viele Aufrufe hintereinander zum Abbruch führt oder man informiert wird. Nun ja, der Aufrufzähler hat mich zumindest darauf aufmerksam gemacht.
Das Programm ist durch ein Passwort gesichert - werde wohl oder übel das Passwort mal ändern.
Grüße
Herbert
Was halt merkwürdig ist, dass das Zählerfeld "0" anzeigt. Ich hätte jetzt gedacht, dass da die letztmögliche (DMax) Zahl angezeigt wird.
Gruß
Herbert
ZitatSchade, dass man da nix einbauen kann, wo ein schnelles Hochzählen durch sehr viele Aufrufe hintereinander zum Abbruch führt oder man informiert wird.
Na, wer wird sich denn selber beschränken. Wenn man will, findet man einen Weg. Die Macht des Wassers ist so gewaltig, dass es der stärkste Mann nicht halten kann.
Neben dem Zählerfeld könntest Du ein Zeitstempelfeld einführen. Damit kann man dokumentieren, wann ein Formular geöffnet wurde.
Nachfolgend könnte man dann im Rahmen der Schreibroutine prüfen, wie groß die Zeitdifferenzen sind oder wieviele Aufrufe bspw. in der letzten Viertelstunde erfolgten, um darauf reagieren zu können.
Bei einer vorhandenen Benutzeranmeldung könnte man auch den aktiven User dokumentieren.
Hallo Herbert,
Welcher Wert steht denn beim Abbruch in der Tabelle?
Schnelles Hochzählen ist doch einfach
Public Function HochZaehlen()
On Error GoTo Fehler
Dim z As Long
'auf Anfang
CurrentDb.Execute "UPDATE tblFormAufrufe SET [AufrufZähler] = 1", dbFailOnError
'x-mal aktualisieren
For z = 1 To 50000 'hier musst da mal experimentieren
CurrentDb.Execute "UPDATE tblFormAufrufe SET [AufrufZähler] = " _
& " DMax('[Aufrufzähler]', 'tblFormAufrufe')+1", dbFailOnError
Next z
Exit Function
Fehler:
MsgBox Err.Number & vbCrLf & Err.Description
End Function
(das Sonderzeichen ä ist mir jetzt erst aufgefallen, deshalb [] ergänzt)
gruss ekkehard
Hallo zusammen,
@ebs17:
das mit dem Zeitstempel muss ich mal probieren, da könnte ich die Differenzen ermitteln und sehen wie die Zeitabstände sind.
@Ekkehard:
der letzte Wert der angezeigt wurde war "0" - das ist ja gerade das was ich eigentlich überhaupt nicht verstehe. Wir hatten allerdings letzte Woche einen Serverabsturz - aber das dürfte doch den Wert des Zählers nicht beeinflussen oder?
Das Hochzählen werde ich auch mal ausprobieren (allerdings müsste das bei LongInteger eigentlich nie und nimmer zu einem Fehler führen)
Vielen Dank noch mal für eure Antworten.
Grüße
Herbert
Streng genommen: Wenn Du einen Zeitstempel verwendest, brauchst Du gar nicht mehr hochzählen, sondern Du könntest schlicht die Einträge zählen.
Und wie gesagt: Die Dichte der Einträge ermöglicht Rückschlüsse auf das Nutzungsverhalten.
Hallo,
ich habe jetzt ein Problem mit dem Anlegen von neuen Datensätzen. Ich habe den Aufrufzähler in der Formulareigenschaft "Beim Anzeigen" gesetzt, während das eigentliche Ausführen "Beim Laden" geschieht:
a) Ausführen (Beim Laden)
CurrentDb.Execute "UPDATE tblFormAufrufe SET tblFormAufrufe.Aufrufzaehler = " _
& " Nz(DMax('Aufrufzaehler','tblFormAufrufe'),0)+1", dbFailOnError
b) Hochzählen (Beim Anzeigen)
Private Sub Form_Current() 'Beim Anzeigen wird die Statusbar (ganz unten) nicht angezeigt
Dim Summe As Long
Dim Aufrufe As Long
Summe = 1
Call Application.SetOption("Show Status Bar", False)
Summe = Summe + (Aufrufzaehler -1)
Aufrufe = Summe
DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
DoCmd.Requery 'Akutalisieren
DoCmd.GoToRecord , Eingabeformular, acLast ' Letzten Datensatz anspringen
End Sub
Wenn ich im Einzelschritt durchgehe funktioniert alles wunderbar, d.h. das Feld "Aufrufe" zählt hoch. Leider wird auch durch das anschließende Abspeichern kein neuer Datensatz in meiner tblFormAufrufe erzeugt und das Tabellenfeld zugehörige Tabellenfeld bleibt leer im Formular. Muss ich hier evtl. ein andere Formulareigenschaft verwenden? Ich könnte das Ganze natürlich auch über eine Abfrage machen, aber das müsste doch auch so gehen oder?
Gruß
Herbert
Hallo zusammen,
nachdem die CurrentDb.Execute... Anweisung nun mehrfach den Geist aufgegeben hat (das Feld im Formular zeigte plötzlich im Formular nur noch den Wert "0" an, obwohl er am Tag vorher noch die richtigen Werte angezeigt hat), habe ich mal versucht das Problem mit dem Aufrufzähler über ein Recordset zu lösen. Bis jetzt klappt es einwandfrei. Hier mal der Programmcode dazu:
Private Sub Form_Load() ' Aufrufzähler aktualisieren
Dim Laufcount As Integer
Dim rst As New ADODB.Recordset
rst.Open "tblAufrufe", ActiveConnection:=CurrentProject.Connection, CursorType:=adOpenKeyset, LockType:=adLockOptimistic
If rst.BOF Then
With rst
.AddNew
.Fields("Aufrufzaehler").Value = 1
.Update
GoTo ersterDurchlauf
End With
End If
With rst
.MoveLast
Laufcount = rst.Fields("Aufrufzaehler") + 1
.AddNew
.Fields("Aufrufzaehler").Value = Laufcount
.Update
End With
ersterDurchlauf:
rst.Close
Set rst = Nothing
End Sub
Ich vermute mal, dass die Probleme mit der CurrentDb.Execute... Anweisung daher kamen, dass der Server auf dem das Programm lag in letzter Zeit zweimal einen Absturz verursachte und dadurch irgendwie ein Wert "0" produziert wurde.
Eigentlich dürfte das Problem nun nicht mehr kommen, da die Werte ja über das Recordset in einer Tabelle abgelegt werden (hoffe ich).
Grüße
Herbert
Hallo Herbert,
ZitatLeider wird auch durch das anschließende Abspeichern kein neuer Datensatz in meiner tblFormAufrufe erzeugt
Wie auch, du aktualisierst ("UPDATE Tabelle ...") ja auch nur einen vorhandenen
DS; - Anfügen geht mit "INSERT INTO Tabelle ..."
gruss ekkehard
Hallo Ekkehard, ok das hatte ich vergessen. Die Version mit dem Recordset funktioniert jedoch auch einwandfrei. Das Problem mit den Serverabstürzen verlangt quasi danach eine Tabelle mit fortlaufenden Datensätzen für die Aufrufe anzulegen. Kostet zwar Speicherplatz aber nach dem Serverabsturz sind die Datensätze noch in der Tabelle vorhanden.
Vielen Dank auch an alle die hier mitgeholfen haben!
Gruß
Herbert