Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim maxDate As Date, Num As Long
If Me.NewRecord Then
maxDate = DMax("日付", "テーブル名")
Num = DLookup("数値", "テーブル名", "日付=#" & maxDate & "#")
If Me.日付 = maxDate Then
Me.数値 = Num
ElseIf Me.日付 > maxDate Then
Num = Num + 1
If Num > 10 Then Num = 1
Me.数値 = Num
End If
End If
End Sub
こんなのだったら、もっと分ける意味がありそうかと思うんですが、
例えば、
例えば、
日付テーブルや詳細テーブルは、それぞれ、どんなフィールドになっているのでしょうか?
推測ですが、かなりのコード量になる、その手間に対して見合う信頼性、安全性が得られるのか、というところだと思います。
そこまで人的コストをかけるなら、SQL Serverの無料版とかその他のデータベースサーバー製品にした方がコストに見合った結果が得られるということだと思います。
ないです。
クエリで連番を取得しようとすると、レコード毎に集計が発生するので指数関数的に重くなりますが、
提示のコードで新規レコードの連番数値フィールドに代入するだけですので、
DMaxやDLookupでの集計、検索は1回だけです。
日付フィールドにインデックスを設定しておくのは、今回の1回だけの集計、検索にも有効ですが、体感できる差はでないでしょう。
ただし、日付フィールドに対して、並べ替え、グループ化、抽出、、、などのデータ操作が発生する場面は多いと思われますので、インデックスを設定しておいた方がいいでしょう。
日付にインデックスを張る(フルスキャンを避ける)
テーブルのレコードは適当なタイミングで削除(アーカイブへ移動、最適化)する
あたりでどうでしょうか
すみません
スマホなのでタイプミスしました
比較することになりますよね?
です
教えて頂いたコードであれば指数関数的に重くなるということもないですか?
全レコードを対象に日付を比較することになりますよねん
たびたびありがとうございます。
なるほどです。Access は知って長いですが、やっと納得できる文章を目にできて感動的ですらあります。
>ワークテーブルや非連結フォームを推奨するサイトや書籍があるのは知ってますが、同時編集の排他処理までをきちんと解説しているものは見たことがありません。
私も結構読んできましたが、私も見たことが無いです。Access 職人の食い扶持として秘密なのか、「だいたい分かるよね?」みたいなことなのか。
ともあれ「解決」でクローズさせていただきたいと思います。
ありがとうございました。
上記の制限に沿っているとして、下記のような感じでしょうか。
そういうことなら、フォームの挿入前処理か更新前処理でVBAで連番数値フィールドで連番を入力していくのがよさそうです。
ただし、入力は日付順に入力するという制限が付きますが、それは大丈夫ですか。
例えば、6/1を入力してから、5/29を入力するというようなことがあると面倒です。
最終的に印刷されればいいですが、印刷のたびに変わると困ります
別紙に1~10までの通し番号がついた安全のための機械の点検項目がかかれたものがあり、
毎日違ったものをやった、という書類をつくるのが目的です
内部監査のようなもので印刷した書類のチェックがあり、一応毎日違ったところを
順繰り点検しました、といった感じです
自動連番フィールド、はACCESS標準機能のオートナンバーです
数値フィールドというところに日が変わるごとに+1した数値を入れていき、
10でリセットといった具合です。伝え方が悪くてすみません
手段はどのようなものでもよいので
| 日付 |数値 |オートナンバー|
|05/31 | 10 |1
|06/01 | 1 |2
|06/02 | 2 |3
と、レコードを追加するたびに自動で”数値フィールド”に数値が入力されればよいです
(上記以外にも手入力するフィールドは多数あります)
この連番は最終的にはどのような目的で使用するものでしょうか。
もし、最終目的が印刷出力なら、レポートの設定で簡単に可能です。
クエリで実現しようとすると、かなり複雑なものになりますし、レコード数が増えるにしたがって指数関数的に重くなりますので、レコード件数が多いときは避けたいですね。
テーブルに「自動連番フィールド」があるなら、VBAで連番を入力しておく方法が比較的シンプルでパフォーマンス的にもお勧めです。
まずは、連番の最終的に使用目的を教えてもらえませんか。
Accessのオプションに、共有モードやレコードロックの設定があるので、連結フォームでの共有は使えるものでしょう。
MSの公式ドキュメントにも下記の記載があります。
この破損する可能性が軽減させるというのがどの程度なのか、は不明確ですので、これをどうとらえるかで結論も変わってくるでしょう。
自身の経験から、これはOKと思っています。(もちろん定期的なバックアップは取ってますが)
それ以上の場合は、 連結フォームでどこまでOKかは分かりません。同じレコードの同時編集を回避すればかなりの人数の共有まではOKではないかと予想してます。
同じレコードの同時編集が頻発する運用だと、連結フォームではきついかなという印象です。
ただ、ワークテーブルや非連結フォームで、同時編集までの排他処理を考慮して設計しようとすると、膨大な工数になるでしょう。また、ワークテーブルや非連結フォームを推奨するサイトや書籍があるのは知ってますが、同時編集の排他処理までをきちんと解説しているものは見たことがありません。
そこまでの信頼性を求めるなら、SQL Server などのデータベース サーバー製品と連携させることを検討したほうがいいようにも思います。ただ、一桁台の人数のでの共有はコスト的に見合わないと思います。
この辺は主観的な部分が多分にありますので、あくまで一個人の意見として参考にしてください。
連投ですみません。整理すると、
大前提 「AccessのDBファイルを長期的に安定して使用するには」のようにする
その上で
・4, 5人までの利用 × 同じレコードの同時編集を回避する -> Access が用意している排他制御で OK
・それ以外 -> ワークテーブルや非連結フォームの実装必須
でいいのでしょうか。結構調べてきたつもりですがなかなか明快な説明に会えず、よろしくお願い致します。
お返事ありがとうございます。
例えば私の手持ちの『Access VBA ポケットリファレンス』(2010年)に「業務システムとして Access を利用するなら、非連結フォームを心がけて下さい」とあり、その他書籍かウェブサイトかを問わずそれ的な情報にしばしば遭遇し、最近の
『Access VBA 実践マスターガイド』(2019年)を確認してもやはり非連結フォーム、SQLでの更新をピックアップしています。ので、Access はそうしないと共有できない仕様なのかと誤解(?)しておりました。
hatena さんは、このあたりどう学習なさったのでしょうか。何か良い書籍をご存じでしょうか。
ちなみに私の当初の質問は「ロックがだめでも楽観的排他制御で工数を省けるなら省きたい」というだけで、楽観的排他制御が主目的だったわけではありません。
前回の回答の設定で「レコードレベルロック」は可能です。
ただし、データベースパスワードを設定できないという制限があります。
(データベースパスワードを設定すると「ページレベルロック」になる。)
AccessのDBファイルを長期的に安定して使用するには - hatena chips
上記でもふれてますが、Access95から機能追加、改修しながら使用してますが、ここ15年間ぐらいはこの設定でデータベースの破損やトラブルはありません。Access2000頃までは、たまに破損していたのでバックアップからリストアしたということはありましたが。
ワークテーブルを使うとか、非連結フォームを使うとか、特別なことはせずに、普通に連結フォームで問題なく運用しています。あくまで、当方の環境と運用においてということですが。
当方の運用
忙しいときは5名で同時入力、ただし顧客毎に担当分けしているので同じレコードを同時入力ということはほぼない。
直々のお出ましありがとうございます。
hatena 様と同じく有線LAN5名程度(小事務所)での使用、フォームからの入力のことで思案しています。
Access(バックエンドが Access の ACE(?))の場合、
レコードレベルロックができない、ページレベルロックしかできずワークテーブルを用意して何だかんだと学んだのですが、
VBA でいろいろとお膳立てしない(Access の機能・仕様の)レコードレベル悲観ロックも
(少人数であれば)普通に実用できるということでしょうか。
このへんいまいち分からず、ご教授いただければ非常にありがたいです。
結果的には方法2でズレもなく印刷できました
詳しく解説していただいて助かりました
方法1について試行錯誤で調整シてみようと思います
方法2については”式”を見つけることができました
いっそのことプリンタの設定にA4横にA5縦を2ページ印刷しようと思いましたが?
このように
画像1
縮小印刷されて大きく余白があいてしまうことになります
レポートをA5縦で作成して、プリンタでは用紙をA4横で2ページ印刷にしています
EXCELではこのような感じでできていたのですが
ACCESSは別途なにか設定が必要でしょうか?
[オプション]→[クライアントの設定]→[詳細設定]での設定のことかな?
私の場合は、デフォルトではなく下記のような設定で運用してますが、
フォームの「レコードロック」プロパティは「編集済みレコード」に設定。
有線LANで5名程度の同時使用でトラブったことはないです。
デフォルトでの場合は分かりません。
環境や運用状況によると思いますので参考までに。
方法1の場合
画像の[印刷設定]の[レイアウト]の[サイズ]の[幅]を 14.674cm から減らすと、2列目が左にずれるので、プレビューが確認しながら少しずつ減らしていって、同じ位置になるように調整してみてください。
方法2の場合
画像の「フィールドの選択」の右の▼をクリックすると、フィールドのリストが表示されてその下に「式」という欄があるのでそれをクリックすると式ビルダーが開くので、そこに「=1」と入力してOKをクリックしてください。
2列めの最初の左位置14.674cmにして


このように設定しましたが([印刷設定]の[レイアウト]の[幅]がなかったので)、このように
1文字程度のズレがでてしまいます。こだわりすぎかもしれませんが、目分量で左右にずらすと
一列目と比較して多少のずれが気になってしまいます
なにか設定がまずいでしょうか?
方法2でやろうと思いましたがグループ化の項目がこのようになっていて

解説して頂いているような数式を入れるところがどこかわかりませんでした
方法2を使わせてもらったとしても、
上記の幅の設定はどうようにするということですので
やはりずれてしまうのでしょうか
度々の質問になりますがよろしくお願いいたします
ヘッダーの2列目の最初の項目ラベルと「左位置」と[印刷設定]の[レイアウト]の[幅]を同じにします。
それでずれているから、デザインビューで項目ラベルの位置を左右にずらしてプレビューして確認しながら、調整すればいいでしょう。
すべてのレコードが同じグループ(一つのグループ)になるということです。
よって、グループヘッダーを表示させると先頭に一つできます。
「セクション繰り返し」を「はい」にすることで各ページの先頭に表示されます。
方法1でやりました
二列目の表示位置の調整方法がわかりません
レイアウトの幅は、どのように2列目の位置に影響をあたえるのでしょうか?
方法2の固定値でグループ化するというのは
=1とするとすべてのレコードが対象になるのですか?
できました。
ありがとうございました😊
具体的にはどのように設定しているもののことでしょうか。
DAOあるいはADOでデータ操作しているときの話なのか、
フォームからデータ入力している話なのかとか。
もう少し具体的に説明してもらえますか。
下記でどうですか。
リンク先では、方法1 と 方法2 の2つの方法を紹介していますが、どちらの方法でしていますか。
方法1なら、[印刷設定]の[レイアウト]の[幅]で2列目の表示位置を調整できますので、それで合わせてください。
方法2ならずれることは考えられません。
レコードソースをバラメータクエリにする方法もありますが、フォーム経由にした方が自由度は高いです。
開くときに設定する条件を都度任意のものにしたいときは
フォームを経由させることになりますか?
レポートをデザインビューで開いて、「レコードソース」プロパティをクエリ名に変更すればいいでしょう。
フィルタリングするだけなら、マクロかVBAでレポートを開くときに抽出条件を設定できますので、レコードソースはテーブルのままにしておけば、レポートは一つですみます。
VBAの場合のコード例
DoCmd.OpenReport メソッド (Access) | Microsoft Docs
まずは問題を切り分けましょう。
問題のファイルの「閉じる時に最適化」をオフにしたときは、バックグラウンドプロセスが残りませんか。
残るなら、「閉じる時に最適化」が原因ではないので、別の部分に原因があることになります。
残らないなら「閉じる時に最適化」をオフにして運用する方法を検討しましょう。
方法としてはタスクスケジューラでWindowsの起動時または終了時に問題のファイルを最適化するプログラムを実行するようにすればいいでしょう。
Accessの最適化をバッチファイルで行う方法 – 外資系SEパパのブログ
Accessデータベースファイルを最適化する関数 - hatena chips
⇒ です。確認がイマイチでした。申し訳ありませんでした。
⇒ 記載しませんでしたがエラーが出て困っておりました。
⇒ 一旦は15列での出力を試みましたが画像が粗く埋め込みにしようかとその為のワークテーブル作りでした。
他に策があればご教授下さいますようお願い致します。
と言うか、新たにトピックを起こします。
hatena様ありがとうございました。
朱色様、
なるほどです。これもやってみます。
こういったデータの並び替えって、需要が結構ありそうだと思っていたんですが、以外に少ないみたいですね。
ありがとうございました。
こんばんは。
色々試してみましたが、結局解決しませんでした…。
とりあえずは、下記の対応で当分は対応しようと思います。
①起動用のaccessの起動
(フォームを表示せず、単体の起動でバックグラウンドプロセスが残らないようにします)
②本体のaccessの使用(最適化はそのままの設定)
③本体を終了(バックグラウンドプロセスが残る)
accessのバックグラウンドプロセスが残っていても、起動用accessから開くと通常通り使用できました。
ただし、起動→本体終了を繰り返した分だけバックグラウンドプロセスは残ります。
私以外のPCは退社時に電源をオフにしますので、
タスクキルもせず、そのままにしようかと思います。
(本当はよくないかと思いますが…)
私のPCは夜間自動更新がありますので、タスクキルのバッチファイルでも作成して、しばらく運用してみようと思います。
「閉じる時に最適化」が原因なのか、とも思いましたが、単体運用しているmdbでは同じ設定でもバックグラウンドプロセスが一度も残らなかったので、違ったようです。
何かご存知の情報などありましたら、ご教示頂ければ幸いです。
コードには
rs.Fields("file_image")
とあるのですが、file_image というフィールドは t_filedetaにあるのですよね。あと、内側の Do Loop の最後でも rs.EOF でチェックしないとエラーになると思います。
蛇足
コードを見た感じ、印刷用ワークテーブルで15列に出力しているのだと思いますが、
レポートの印刷設定で列数を設定できますのでそれでいいように思いますか、
なにか特別なレイアウトになっているのでしょうか。
回答するのに情報が不足しているということです。
実際のテーブルのデータ例と欲しい出力結果を提示してもらえませんか。
お試しクロス集計クエリを作ってみたけれど、過去1年間の絞り込み条件式が難しいという事でしょうか?
それと、過去1年間とは、いつからと考えていますか?
テーブル[T-取引]のデータ例を提示してもらえますか。
在庫量の計算は一般的に、期首在庫量+入庫量-出庫量 という計算になりますが、期首在庫量をどこにどのように格納しているのでしょうか。
こんばんは。
タブ・スペース・改行の違いがよく分かりました。ありがとうございます!
タブ文字が文字化けしていたのですね。アプリケーション依存で表示されるとは知りませんでした。
クエリに式を入れていたのですが、テキストボックスの更新後処理の方がスマートですね、変更してみます!
返信遅くなりました。
うまくいかない理由が分かりました。ありがとうございました。