- 締切済み
Accessのデータベースを使用した社員のログ管理
OS:WindowsXP Access Version:Access2003 Table:[Tログ管理] (フィールド)ID/ログイン日/ログイン時/ログアウト日/ログアウト時/社員番号 Form:[ログイン] [メインメニュー] コマンドボタン:”ログイン”([ログイン]フォームに配置) ”終了”([メインメニュー]フォームに配置) Accessでデータ管理システムを構築しております。 数十名の社員が使用する予定です。 そこで、どの社員がいつ・何時に使用したのかログ管理をしたいと考えております。 考えている方法として、 (1)Access(システム)を起動すると、[ログイン]フォームが表示されます。”ログイン”コマンドボタンをクリックします。 (2)すると、[Tログ管理]のID(オートナンバー)/ログイン日/ログイン時/職員番号にそれぞれ登録されます。 (3)”ログイン”コマンドボタンをクリックした後は、[メインメニュー]フォームが表示され、[ログイン]フォームは閉じます。 (4)[メインメニュー]フォームには、作業の内容を題したコマンドボタンを配置予定です。そして一番下に”終了”コマンドボタンを配置、クリックすると先ほどの[Tログ管理]から社員番号の入ったレコードを検索し、ログアウト日・ログアウト時を登録したいのです。 この「ログイン」コマンドボタンのクリック時イベントに下記のようなコードを記述しました。このコードで(2)(3)の動作はしてくれます。 ************* Public Sub ログイン_Click() Dim mySID as Object Dim CN as ADODB.Connection Dim RS as ADODB.Recodset Set mySID=CreateObject("Wscript.Network") Set CN=CurrentProject.Connection Set RS=New ADODB.Recordset RS.Open "Tログ管理",CN,adOpenKeyset,adLockOptimistic RS.AddNew RS!ログイン日=Date RS!ログイン時=Now RS!職員番号=mySID.UserName RS.Update RS.Close: Set RS=Nothing CN.Close: Set CN=Nothing DoCmd.OpenForm"メインメニュー",acNormal DoCmd.Close acForm,"ログイン" End Sub ************************** ”終了”コマンドボタンのクリック時イベントに(4)の作業をしてくれるコードを記述したいのですが、FilterやFindの使い方がよくわからなくて、前に進めません。。。 社員番号から検索せずにオートナンバーのIDを引数で渡す方法もありなのかな?と思ったのですが、初心者のため、どちらが効率的なのかわからないので、効率的な方法がありましたらどうか教えてください。 初心者なので、誤字脱字・読みにくい箇所があると思いますが、どうぞご容赦ください。 丁寧に教えてもらえると助かります、よろしくお願いいたします★
- みんなの回答 (2)
- 専門家の回答
みんなの回答
#1のご回答で主要部分は解決済みと思います。いくつか蛇足を 1.”終了”コマンドボタンのクリックをせずに、システムをダウンさせる乱暴なユーザーや、停電などの事故によるログアウト対策 色々な方法が考えられるでしょうが、一案としてフォームのプロパティシートのイベントタグで、タイマー間隔を60000(1分)にし、タイマー時のイベントプロシージャに Private Sub Form_Timer() 'ここに#1のご回答にある Dim CN As ADODB.Connection Dim RS As ADODB.Recordset Set CN = CurrentProject.Connection Set RS = New ADODB.Recordset With RS Dim StrSQL As String '→この行は、他の変数宣言と同じ場所に移動可 'テーブル名の代わりとなるSQL文を、変数に記録 StrSQL = "Select * From Tログ管理 Where ID=" & Me.OpenArgs & ";" '「テーブルを開いて当該IDのレコードに移動」の代わりに、 'SQLにより、当該IDの1レコードに限定して開く .Open StrSQL, CN, adOpenKeyset, adLockOptimistic !ログアウト = Now .Update End With RS.Close: Set RS = Nothing CN.Close: Set CN = Nothing End Sub 2.ログアウトしないで他の業務を開始し、「実質的にはログアウト」している対策 キーボードに対する操作を監視します。 'グローバル変数に Dim LastAccessTime As Date 'フォームを開くとき Private Sub Form_Open(Cancel As Integer) LastAccessTime = Now End Sub 'キー操作があれば Private Sub XX_KeyPress(KeyAscii As Integer) LastAccessTime = Now End Sub 'タイマーで記録するとき !ログアウト = Now→!ログアウト = LastAccessTime など。ちなみにこのログは何を目的として収集するのでしょうか?
- DexMachina
- ベストアンサー率73% (1287/1744)
私自身は、ADOではなくDAOを使用しているので、効率などに関して一部誤解があるかも しれませんが・・・(汗) > どちらが効率的なのかわからない ログ管理となると、社員番号1つに対して複数のレコードが存在するはずですので、 社員番号で検索・絞り込みを行うには、社員番号以外の情報(→ログイン日時が最も 遅いもの、等)が必要になります。 その意味で、1フィールドで1レコードを特定できる「ID」を使用した方が、効率的かと 思います。 また、同様に、何かで「最後のログイン日時」の検索が必要になった場合を考えると、 「ログイン日」「ログイン時」は「ログイン日時」にまとめた方がよいように思います。 (ログアウトについても同様) とりあえず、「IDを元にして記録先を特定」とするには、終了ボタンがあるメインメニューに その「ID」を渡す必要がありますので、ログインボタンでのメインメニューを開くコマンドを、 以下のように変更してください: Private Sub ログイン_Click() Dim mySID As Object Dim CN As ADODB.Connection Dim RS As ADODB.Recordset Dim CurID As Long Set mySID = CreateObject("Wscript.Network") Set CN = CurrentProject.Connection Set RS = New ADODB.Recordset With RS 'RSに対する一連の処理をWith内にまとめました .Open "Tログ管理", CN, adOpenKeyset, adLockOptimistic .AddNew !ログイン日時 = Now !職員番号 = mySID.UserName .Update CurID = !ID 'オートナンバーのIDを変数CurIDに記録 End With RS.Close: Set RS = Nothing CN.Close: Set CN = Nothing Set mySID = Nothing 'OpenFormの引数OpenArgsで、メインメニューにCurIDを渡す DoCmd.OpenForm "メインメニュー", acNormal, , , , , CurID DoCmd.Close acForm, "ログイン" End Sub これで、ログイン時に割り当てられたIDを、メインメニュー側で使用可能になります。 (OpenFormの7番目の引数OpenArgsの値は、呼び出されたフォーム側では Me.OpenArgsという式で参照できます) 次に、メインメニューの終了ボタンのコードです: Private Sub 終了_Click() Dim CN As ADODB.Connection Dim RS As ADODB.Recordset If MsgBox("終了します。", vbOKCancel) = vbCancel Then Exit Sub Set CN = CurrentProject.Connection Set RS = New ADODB.Recordset With RS .Open "Tログ管理", CN, adOpenKeyset, adLockOptimistic '「Find」メソッドにより、ログイン時に取得したIDのレコードに移動 .Find "ID=" & Me.OpenArgs !ログアウト日時 = Now .Update End With RS.Close: Set RS = Nothing CN.Close: Set CN = Nothing 'アプリケーションを終了 DoCmd.Quit acQuitPrompt End Sub ・・・以上です。 ただ、Findだと「テーブルを読み込み→該当レコードに移動」ということになる分、 SQLを使用した方が効率的かもしれません。 この場合は、上記の「With RS」から「End With」までを以下のものに差し替えます: With RS Dim StrSQL As String '→この行は、他の変数宣言と同じ場所に移動可 'テーブル名の代わりとなるSQL文を、変数に記録 StrSQL = "Select * From Tログ管理 Where ID=" & Me.OpenArgs & ";" '「テーブルを開いて当該IDのレコードに移動」の代わりに、 'SQLにより、当該IDの1レコードに限定して開く .Open StrSQL, CN, adOpenKeyset, adLockOptimistic !ログアウト = Now .Update End With ※テーブル保存先のバックエンドと、フォームやモジュールの保存先のフロントエンドに 分割されている前提としています。 分割されていない場合、同時使用によって他のユーザーの取得したIDで上書きされ たりしないかどうかは検証していません。 (なお、複数人での同時使用を考えると、ファイル破壊回避のため、分割をお勧めします: それでも数十人の同時使用は、Accessでは厳しいと思いますが(汗))
お礼
ありがとうございました!