• 締切済み

アクセス:フォームを閉じずにデータ更新するには

みなさん、おはようございます。 データベースアクセスについて質問させていただきます。参考書やこちらの質問等もしらべましたが回答が得られなかったので質問致します。 現在、アクセスで病院のベッドを管理するアプリを開発中です。 ひとつのフォームに全病棟のベッドを表示するため500以上のコントロールを配置しておりますが、 すべて非連結にして、フォームを開くときのイベントプロシージャーにクエリを開いてすべてコントロールにテーブルのデータをはめていくように設計しています。 で、問題はこのフォームを開いたまま最新のデータに更新させたいのですが、再クエリーではうまくいきませんでした。 なぜうまくいかないのか理由はわかっていません(プログラマーの方ならうまくいかなくて当然とおっしゃるかもしれませんが) で、仕方なく、一定間隔の時間ごとにフォームを閉じて開くという方法を取っています。 この方法では遅いマシンだと再表示に時間がかかるのできっとほかにスマートなよい方法があるとおもっているのですがプログラミングのスキルが乏しいため詰まっております。 お知恵をお借りできれば幸いです。

みんなの回答

noname#182251
noname#182251
回答No.11

平面的に表示し、定期的に情報を更新するフリーのアプリケーションを見つけました。 http://awplus.jp/soft/page1/aj/bedmng.html プロトタイプということなので、実用にはならないでしょうが、ソースコードが公開されているために、参考にはなりそうです。オブジェクトを配列で管理しています。言語はデルファイみたいですが。

noname#182251
noname#182251
回答No.10

>>おぼろげに、配列を使えばきっとシンプルにできるんだろうな~と感じていましたが. . . . 配列とオブジェクト指向を組み合わせるのに、好適なケースかもしれません 1.エディットから派生させたクラスに、データベースとのI/Oなどを追加する 2.エディットの替わりにパネルなどから派生させれば、複数の情報を、テキストボックスだけではなく、ラジオボタン、チェックボックス、コンボボックスなどを使って多彩な表示ができる 3.オブジェクト(病床)にフォーカスがあるとき、当該レコードとつながるようにすれば、マルチユーザーによるデータの矛盾もデータベースが面倒をみてくれる 4.表示位置情報などはデータベースで管理すれば、フォーム上への配置は動的に行え、それ以後の管理は配列でできる 5.病床の増減もプログラムをいじらずにデータだけで処理できる 6.改修工事などによる一時的病床の使用不可も、フラッグなどで簡単に処理できる 7.コードは基本的な部分は数十行ですむ(?) 興味深いです。プロトタイプを作ってみたくなった。 しかし、VBAではほとんど不可能だと思います。一般的にはC++とかC#、ジャバあたりですかね?

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.9

>>おぼろげに、配列を使えばきっとシンプルにできるんだろうな~と感じていましたが、まったくスキルがなくどうすればいいのかわからないのでコードが大きくなることを承知で簡単なコードをベッドごとに書きました。  その配列を使った共通ルーチンを最初に作った人は、オフコン画面の操作性を実現しようという発想でした。でも、簡単にはできあがらず、その会社(当時いた会社)の社長は、売上が無いため「こりゃ首をくくるしかないか?」と枝ぶりのいい木を探したそうです。だから、ちょっと考えて、できそうに思えても、完成するまでの道は長いですね。  それから、私もVBの書籍をたまに見ることありますが、同様なロジックで作ったものは見たことありません(探す範囲が狭いかも?)。ちなみに、似たような考え方のルーチンは、アメリカのデータベースソフトの画面入力関数(C言語)で目にしたことはあります。でも、膨大な関数群で構成されていて、またポインタのてんこ盛り状態で、これは、「天才の仕事だ。絶対自分には作れない!」と思い知らされたもんでした。

noname#79209
noname#79209
回答No.8

全部のベッドを見せなくても、 退院、手術、検査等の監視の必要があるベッドだけ表示させ、 変更がかかったら再表示させたらどうでしょうか? 今日、明日、明後日、一週間以内などを色別に表示させるのも良いでしょう。

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.7

補足です。 >>「500以上のコントロール」などというのもすごい力業だし。 私の場合は、コントロールを配列で操作し、基本的な処理を共通ルーチン化して処理していましたね。 ですので、コントロールが3つでも、500でも、その部分のコード増大はありませんでした。でも、フィールドによってチェック内容が増えるなどは当然あるので、コントロール数に応じて、コードは大きくなりました。

stockman
質問者

お礼

おぼろげに、配列を使えばきっとシンプルにできるんだろうな~と感じていましたが、まったくスキルがなくどうすればいいのかわからないのでコードが大きくなることを承知で簡単なコードをベッドごとに書きました。ベッドのコントロールの修正が発生すると多大な労力になるのは辛いですが・・・ 配列の勉強してみようと思います。 lv4uさんのお話と同じで、当院でも一画面で直感的に空きベッドを把握したいのと、転室処理の場合にもすべてのベッドが表示されていなければ、いちいちが画面操作が必要では面倒この上ないのです。 現場はできるだけ操作がないに越したことはないですから。 余談ですが、ちなみにこの病棟画面は40インチモニタに表示します。

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.6

回答への批判は禁止されていますが、私も同様に思ったことがあるので、補足として回答します。 No.5さんが >>120床を一度に見せる必要があるのかが疑問です。 と疑問をもたれていますが、私も介護のシステムを検討していたとき「なんで一度に見せないといけないの?」と思ったことがありました。 でも運用シーンでは、別の仕事をしていて手が離せず、TVを見るように、何の操作もしないで1画面だけに全ての情報を盛り込んで表示させておき、近くを通ったとき、「ちらっと見る」という使い方をすることもあるとのことで、納得しました。 No.4さんが >>そもそも非連結にしているためにいろいろ問題が発生すると考えます。 と問いかけられています。私も初めてちょっと凝ったマルチユーザでの利用を想定したアプリをアクセスで作成したとき、「非連結にするんだよ」と先輩に指導され「コードが増えるのに・・・」と思ったものです。でも、ちょっと凝った処理では、そうしないとプログラムの作成は不可能でした。もちろん、その影響でコーディング量はいやというほど増えましたね。「これって、ほとんどVisualBasicで作っているパッケージのルーチンからコピっているじゃあないですか?」って状態でした。

noname#79209
noname#79209
回答No.5

120床を一度に見せる必要があるのかが疑問です。 メインフォームの詳細セクションにリスト表示させ、ここに入力用のボタンを置き、 これをクリックすると別フォームで入力用フォームが表示されるようにし、 入力完了後「登録」ボタンを押すとテーブルを更新するようにすれば如何でしょう。

noname#182251
noname#182251
回答No.4

そもそも非連結にしているためにいろいろ問題が発生すると考えます。マルチユーザーでの表示で整合性を取ろうと苦労されているようですが、表示はうまくいっても、複数ユーザーがデータを書き換えたときの不整合にはどのように対応されるのでしょうか?通常ここら辺はデータベースがそれなりに処理してくれる部分ですが、非連結となれば、設計者が処理しなければならない。 「500以上のコントロール」などというのもすごい力業だし。 このようなハードルがあっても、なお非連結にしなければならない理由は何でしょう? これを明らかにされると別のアドバイスもあるかと考えます。

stockman
質問者

お礼

500以上になる理由は、120床あるベッド情報を一度に表示する必要があるためです。 患者氏名、退院予定日等1ベッドあたり4項目の情報を表示します。 また、トップの要望で分りやすいインタフェースでベッド情報の並びが不規則にならざるおえず、単純に帳票フォームを使えないからです。 非連結にするのは、1ユーザがテーブルを開いてデータを握ったままにしておきたくなかったからです。 追加、更新、削除はすべてクエリーで行います。 整合性については、ベッドごとにフラグ用フィールドを設けて、フラグを立てたユーザ以外はデータの参照しかできないようにする予定です。 このシステムは一日に10名も動かない入退院情報を管理するので、競合の発生率はきわめて低いと考えております。 以上が私なりの設計構想ですが忌憚ないアドバイスを頂ければ幸いです。

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.3

>>フォームを開いたときに記述した内容のコードをそっくりタイマーイベントに記述すればいよいとおもったのですが、そうすると修正する場合、2箇所も変更する必要があるので、汎用モジュール化して、それをフォームを開くときとタイマーイベントに設定すればよいと思いましたがいかがでしょうか?  汎用モジュール化でもいいのですが、そこまでしなくとも、普通のプロシージャを作成して、フォームオープン時とタイマーイベント時の両方のイベントから呼び出すようにすれば、コードの2重化は防げると思います。イベント共用がうまくいかない場合は、それぞれの小さなイベントプロシージャから、画面設定のプロシージャを呼び出すという手もありますね。 >>おっしゃるとおり、アクセスでの運用は正直怖いのですが、そこまで病院全体がシステムを使いこなせるようになったら、本格的にオーダリングや電子カルテを導入するようになると思います。いつのことやらですが。  開発の分量を考えてみると、病院のベテラン担当者が協力会社のSEやPGさんを使いまくっても、ちょっと難しいと思いますよ。日本を代表する巨大なメーカでさえ、納品したシステムがトラブルをおこして、大病院のカルテシステムが停止し、薬が出せない状態になったこともありますしね。別のところでは、システムの保守担当が、トラブル対応が激務なため、どんどん辞めていったとか、ダウンして、その病院にお世話になった話など聞きます。(しかも、システムがまともに動作しないわけだから、徹夜などで頑張っても医師や看護師からは冷たい目で見られる)  政府は、全国共通な電子カルテシステムを作る構想があるようですから、それを待ったほうがいい気もします。ただ、丸投げ体質、ゼネコン体質の日本のIT業界で、まともなシステムが作れるか?すごく疑問なんですけどね。

noname#22222
noname#22222
回答No.2

非連結フォームは、多少、専用の関数を用意しないと開発が面倒です。 DisplayRecord() UpdateRecord() DeleteRecord() などです。 これらの関数一発で、フォームへの表示、書き込みも可能です。 また、抽出すべき主キーを配列変数にすれば、レコード移動ボタンの全ても自作することが可能です。 もちろん、サブフォームまで非連結にすると大変ですので主フォーム程度がお勧めです。 Private Sub Form_Load()   Dim StopNow As Boolean      StopNow = Not DisplayRecord(Me, "SELECT * FROM id管理表 WHERE id_name='Test'")   If Not StopNow Then     Message "フォームが正常に表示されました。"   End If End Sub  StopNow = Not UpdateRecord(Me, "SELECT * FROM id管理表 WHERE id_name='Test'")  UpdateRecord関数は、いわゆる非連結フォームに入力されたデータをデータベースに書き込む関数です。書き込む表の列とフォームに配置したコントロールとの対応関係は、DisplayRecord関数と同じようにコントロールの名前で判断します。 ? DeleteRecord("SELECT * FROM id管理表") True まあ、一介のデザイナーに過ぎない素人が考えた関数です。 が、多分、非連結フォームで開発するのに必要なアイデアが含まれています。 なお、その他に、採番テーブルを管理する関数が必要なのは言うまでもありません。  Private Sub 仕入先名_BeforeUpdate(Cancel AS Integer)     Dim strShiiresaki AS String     Dim strWhere   AS String          strShiiresaki = Nz(Me.仕入先名, "")     strWhere = "仕入先名='" & strShiiresaki & "' AND id<>" & Me.ID     Cancel = CBool(DBLookup("id", "仕入先", strWhere, 0) <> 0)     If Cancel Then       Message "[仕入先名]が重複しています。" & chr$(13) & chr$(13) & _           "・{Esc}{Esc} で入力を取り消すことができます。"     ElseIf isNewRecord And Me.ID = 0 Then       Me.ID = NewID("仕入先_id")       SetFieldEnabled Me, True     End IF   End Sub ' ----------------------------------------------------------------------------------------- ' フォームに読み込んだ列情報を表示します。 ' ' 【要件】 ファームのフィールド名が、<"field_" + 列名>であること。 ' ----------------------------------------------------------------------------------------- Public Function DisplayRecord(ByVal frm As Form, _                ByVal strQuerySQL As String) As Boolean On Error GoTo Err_DisplayRecord   Dim isOK As Boolean   Dim I  As Integer   Dim N  As Integer   Dim rst As ADODB.Recordset   Dim fld As ADODB.Field   isOK = True   Set rst = New ADODB.Recordset   rst.Open strQuerySQL, _        CurrentProject.Connection, _        adOpenStatic, _        adLockReadOnly   If Not rst.BOF Then     ' =================     ' Begin With: frm     ' -----------------     With frm       N = .Controls.Count - 1       For Each fld In rst.Fields         For I = 0 To N           If Mid$(.Controls(I).Name, 7) = fld.Name Then             .Controls(I).Value = fld.Value             Exit For           End If         Next I       Next fld     End With     ' ---------------     ' End With: frm     ' ===============   Else     MsgBox " フォームに表示する情報はありません。(DisplayRecord)", vbInformation, " お知らせ"   End If Exit_DisplayRecord: On Error Resume Next   rst.Close   Set rst = Nothing   DisplayRecord = isOK   Exit Function Err_DisplayRecord:   isOK = False   MsgBox "実行時エラーが発生しました。(DisplayRecord)" & Chr$(13) & Chr$(13) & _       "・Err.Description=" & Err.Description & Chr$(13) & _       "・SQL Text=" & strQuerySQL, _       vbExclamation, " 関数エラーメッセージ"   Resume Exit_DisplayRecord End Function Public Function UpdateRecord(ByVal frm As Form, _              ByVal strSQL As String, _              Optional Echo As Boolean = False) As Boolean On Error GoTo Err_UpdateRecord   Dim isOK  As Boolean   Dim I    As Integer   Dim N    As Integer   Dim fldName As String   Dim cnn   As ADODB.Connection   Dim rst   As ADODB.Recordset   Dim fld   As ADODB.Field   isOK = True   Set cnn = CurrentProject.Connection   ' =================   ' Begin With: cnn   ' -----------------   With cnn     .Errors.Clear     .BeginTrans        Set rst = New ADODB.Recordset     rst.Open strSQL, _          cnn, _          adOpenStatic, _          adLockOptimistic     ' =================     ' Begin With: rst     ' -----------------     With rst       If Not .BOF Then         N = frm.Controls.Count - 1         For Each fld In .Fields           For I = 0 To N             fldName = frm.Controls(I).Name             If Left$(fldName, 6) = "field_" Then               If Mid$(fldName, 7) = fld.Name Then                 fld.Value = frm.Controls(I).Value                 Exit For               End If             End If           Next I         Next fld         .Update       End If     End With     ' ---------------     ' End With: rst     ' ===============     .CommitTrans   End With   ' ---------------   ' End With: cnn   ' ===============   If Echo Then     MsgBox " 1件のレコードを更新または保存しました。", vbInformation, " お知らせ"   End If Exit_UpdateRecord: On Error Resume Next   rst.Close   Set rst = Nothing   UpdateRecord = isOK   Exit Function Err_UpdateRecord:   isOK = False   If cnn.Errors.Count > 0 Then     ErrMessage cnn.Errors(0), strSQL     cnn.RollbackTrans   Else     MsgBox "プログラムエラーが発生しました。(UpdateRecord)" & Chr$(13) & Chr$(13) & _         "・Err.Description=" & Err.Description & Chr$(13) & _         "・SQL Text=" & strSQL, _         vbExclamation, " 関数エラーメッセージ"   End If   Resume Exit_UpdateRecord End Function Public Function DeleteRecord(ByVal strSQL As String, _                Optional ByVal Echo As Boolean = True, _                Optional ByVal LockType As Integer = adLockPessimistic) _                As Boolean On Error Goto Err_DeleteRecord    Dim isOK As Boolean    Dim N  As Integer    Dim cnn As ADODB.Connection    Dim rst As ADODB.Recordset       isOK = True    Set cnn = CurrentProject.Connection    ' =================    ' Begin With: cnn    ' -----------------    With cnn      .Errors.Clear      .BeginTrans      ' ----------------      ' Recordset Open      ' ----------------      Set rst = New ADODB.Recordset      ' =================      ' Begin with: rst      ' -----------------      With rst        .Open strSQL, _           cnn, _           adOpenStatic, _           LockType        If Not .BOF Then          .MoveFirst          Do Until .EOF            N = N + 1            .Delete            .MoveNext          Loop        End If      End With      ' ---------------      ' End With: rst      ' ===============      If Echo Then        MsgBox N & " 件のレコードを削除しました。", vbInformation, " お知らせ"      End If      .CommitTrans    End With    ' ---------------    ' End With: cnn    ' =============== Exit_DeleteRecord: On Error Resume Next    rst.Close     ← rst、cnn は、関数から抜け出すと自動的に閉じられ破棄されます。    cnn.Close       よって、これらのコードは省いても支障のないものです。    Set rst = Nothing    Set cnn = Nothing    DeleteRecord = isOK    Exit Function Err_DeleteRecord:    isOK = False    If cnn.Errors.Count > 0 Then      ErrMessage cnn.Errors(0), strSQL      cnn.Rollbacktrans    Else      MsgBox "プログラムエラーが発生しました。" & _         "システム管理者に報告して下さい。(DeleteRecord)", _         vbExclamation, " 関数エラーメッセージ"    End If    Resume Exit_DeleteRecord

stockman
質問者

お礼

>>s_huskyさん 回答ありがとうございます。 このコードの山は厳しいですね^^; マクロ主体で自動化している私には正直???です。 ごめんなさい。 シンプルな方法があると思っていたものですから。 こういうやり方もあるっていうことは参考にさせていただきます。

関連するQ&A

  • アクセスのフォームについて

    アクセスのフォームについて2件質問させてください。 その1 クエリーからあるフォームを作っていますが、元になるクエリー(テーブルにも)には項目がなく、ただそのフォームに表示されればいいというデータをそのフォーム上で入力したいのです。 そこで非連結でテキストボックスを作ったのですが、1ヶ所に入力するとどのページにも同じデータが表示されています。 それぞれのページに違うデータをフォームから直接入力するにはどのようにしたらいいでしょうか? その2 大変むずかしい依頼がきて悩んでいます。 フォームでラベルや図形で1ヶ月を3等分した簡単な図を作り、 フォーム上のある日付をその図の中に●や▲で表示したいのです。 イメージは下のような感じですが、このようなことは可能でしょうか?      2002/3       2002/4           ┃  │   │  ┃  │ ● │  ┃   以上2件一緒にして申し訳ございませんが、ご存知の方がいらっしゃいましたらよろしくお願いします。

  • Accessのフォーム

    Access2003を使用しています。 テーブルまたはクエリを元に作成したフォームにはテーブル・クエリに入力されているデータが表示されますよね? それらのデータをフォームから変更出来ないようにする方法はありますか? データ自体を非表示(入力用フォーム)にするのではなく、既存のデータは表示されるけど変更は出来ないという状態にしたいです。 ちなみに新規入力は行えるようにしておきたいです。 よろしくお願いします。

  • ACCESS フォームの表示

    ACCESSでフォームにクエリを付けて記入してます。 そのフォームは、顧客名簿の様な物です。 クエリには顧客名簿一覧と書類提出日を連結させてます。 他にも同様のフォームがありますが、そのフォームには一度入力したデータがフォームを開くと反映されてますが、 今回作ったフォームには記入したデータが反映されません。 フォーム上で右クリック⇒フィルタの削除 を選択すると入力したデータが表示されます。 しかし、一度閉じるとまた何も表示されていない状態です。 このフォームには、何故データが表示されないのでしょうか?? ご存知の方。よろしくお願いいたします。

  • ACCESSフォーム上サブフォーム内データ更新

    サブフォーム単体なた YES/NO型のデータを更新できるのですが フォーム上に張り付いたサブフォームから YES/NO型フィールドをクリックすると 「このコントロールは***フィールドに連結している為 編集できません」と 表示されます。 何が原因か よくわかりません。 どなたか ご教授御願いします。

  • AccessVBA 帳票フォームの非連結コントロールにデータを入力したいが

    AccessVBAの質問です。 フォームを帳票フォームにして、一覧形式でデータを表示しています。 その中に、データ元となるクエリーとは関係なく、非連結のコントロールが一個あります。 そこに、自由に値を入力して、テーブルへ更新したいのですが・・・。 値を入力すると、一覧上の同じコントロールすべてに同じ値が自動的に入ってしまいます。 行ごとに違う値を入力するにはどうしたらよろしいのでしょうか。 よろしくお願いいたします。

  • ACCESSのフォームについて

    いつもお世話になっております。 Accessですでにあるデータベースに新しいマスタを追加し、テーブルに挿入しました。リレーションシップで連結しました。  フォームに新しくそのデータを表示するテキストボックスを作ったのですが、プロパティのコントロールソースに新しいマスタの項目がなく、新しいマスタのデータを表示できません。 新しいマスタを後から追加した場合、もう一度フォームウィザードで作り直す方法しかないのでしょうか? 普通は設計段階でこのようなことがないようにすると思いますが、なにぶん、データベースに関しては初心者なのでこのようなことになってしまいました。 どうぞよろしくお願いします。

  • Access2000 フォームでのデータ入力について

    質問させていただきます。 Access2000で、あるフォームを作りました(帳票フォーム)。フォームの基になるレコードソースはクエリーです。このクエリーは原料伝票テーブルから在庫数が特定の数量を下回った原料を抽出しています。 フォームは以下イメージです。 原料コード 原料名  在庫数  発注数 原料コード~在庫数をクエリーから、発注数を手入力 にしました(発注数のコントロールソースは非連結です)。 で・・・発注数に値を入力すると全部の行が同じ値になってしまします。これを改善したいのですが・・・。 このやり方は根本的に間違っているのでしょうか?

  • アクセスでフォームが消える(3回目)です

    何回もすみません。 アクセスのフォームでデザインビューでは表示されるが、データーシートビューでは表示されないの件ですが、フォームの問題ではなく、元になっているクエリーの問題のようです。 クエリーに追加表示するテーブルによって、クエリーの時点で詳細行が消えることがわかりました。 そのため、フォームでも表示されないようです。 が、解決方法が見つかりません。 よろしくお願いします。

  • access2010 フォームについて

    access2010 フォームについて accessにテーブルを2つ作成しています。 A  ・コード    B   ・コード                 ・内容 一コードに対して内容は複数あります。 コードをリレーションしたクエリを作成し、そのクエリを使用したフォームを作成していて困っています。 あらかじめ作成してあるエクセル表を非連結オブジェクトフレームで貼り付け(お絵かき添付)、左上にコードのコンボボックスを作成して下の欄に内容を表示させたいのですが、内容を複数件表示させる方法がわかりません。 宜しくお願いします。

  • ACCESS97のフォームについて

    アクセス97のフォームについて教えてください。 前にも質問したのですが、アクセスのバージョンの記述を忘れていましたので 再度ご質問させていただきます。 DATAというテーブルがあります。DATAテーブルをフォームに以下のように表示したいと考えています =====================================================================   DATA選択画面 部門 日時 件数 区分 選択 ------------------------------- --- --- --- --- □ ←チェックボックス --- --- --- --- □ --- --- --- --- □ --- --- --- --- --- --- --- --- □ ------------------------------- ==================================================================== 区分が1のものは普通に表示して、区分が2のものは字の色を灰色にしたいと考えています --- の明細の部分(DATAテーブル)を順番に区分を判断しながらフォームに 表示していくということは可能でしょうか? ちなみにクエリオブジェクトは使用しないのが前提です。 SQLクエリはOKです。 アクセス2000であれば条件付き書式でこのようなことが可能だということは 分かっているのですが...97で出来るのでしょうか? かなり切羽詰っています。宜しくお願い致します