If Me.カウント.Value = 10 Then Me.改ページ.Visible = True
'ページヘッダーでFalseにしているので毎レコードごとにプロパティを設定する必要はない'
③[カウント]テキストボックスの値を0にする理由
初期化処理については、VBAでDim i As Longとした場合は変数宣言のルールによりiには0が入っていますが、今回はフォーム上に[カウント]テキストボックスを設置していますので、フォーム上のコントロールの設定(規定値プロパティ)に従ってMe![カウント]の値はNullになっているのだと思います。VBAの初期化を使いたいのならモジュール先頭で
Private Sub ユーザー情報変更_Click()
If IsNull(PF_CMB_個人ID) Then
MsgBox "編集する人間の個人IDを入れてください"
Exit Sub
End If
DoCmd.OpenForm "ユーザー情報編集フォーム", , , "個人ID=" & Me.PF_CMB_個人ID.Value
End Sub
hirotonさんが丁寧に解説されているので、感想だけ。
確かに冗長な部分があるコードだと思います。
行数をカウントするのに変数を使わずにテキストボックスを使うとか。
改ページをコントロールするのも、改ページコントロールの可視を変更するというのも、私は使いません。
改ページコントロールの位置が最下部からずれると想定外の動作になったりするので。
ForceNewPageプロパティで改ページを制御しますね。
SendObject では一つのオブジェクトしか送れないようです。
メールソフトがOutlookならそれを操作して添付するとか、別の方法を検討するしかないでしょう。
最初の質問のSQLでうまくいかないということですか?
そのSQLをクエリのSQLビューに記述して開いた場合は、希望の結果が表示されますか。
というか、現状のうまくいかないコードを先に提示してください。
データシートビューの中で、各フィールドの枠付近にマウスカーソルを合わせると十字のアイコンに変わります。その状態でドラッグすると複数のフィールドが選択できるのでそれで貼り付けが可能です。
そうですか!それも試してみたのですが1つのセルに全部データが入るような感じで貼り付けできませんでした。
何か貼り付けの方法がありますでしょうか?
こんにちは。
'''
strAPPT = SysCmd(acSysCmdAccessDir) & "\MSACCESS.EXE"
’’’
と書き換えて、今のところ32bit、64bit共に問題なく起動できています。
来週pcの入れ替えが始まるので、Windows10で最終テストしてみます。
とりあえず、お知らせまで。
良いか悪いかは別にしてデータシートビューなら貼り付けできますね
考えられている通り、詳細_Format側を弄ればいいんじゃないかなと思います
初期化処理については、VBAで
Dim i As Long
とした場合は変数宣言のルールによりiには0が入っていますが、今回はフォーム上に[カウント]テキストボックスを設置していますので、フォーム上のコントロールの設定(規定値プロパティ)に従ってMe![カウント]
の値はNull
になっているのだと思います。VBAの初期化を使いたいのならモジュール先頭でのように変数を用意すればいいと思います。
また、データ件数が10件を超える場合、2ページの描画処理に入ったタイミング(のページヘッダー)で行数カウントをリセットしないと2度と
Me.カウント.Value = 10
がTrue
になることがないので困ったことになります。(このコードなら20件までは問題ないように動きますが)今回の件では変数の初期値自体は二の次の話ですね。
hatena様
返信遅くなりました。回答ありがとうございます。
strSQL = "サブクエリを含むSQL"
””の中にSQL文を記載したのですが、書き方が悪いのか実行できません。
また、( など、どのように記載するのか分かりません。
本当に図々しいお願いですが、このコードをどのように記載するのか、
お手本を見せていただけないしょうか?
hatenaさん
解説ありがとうございます。解説を基に色々コードをいじって確認してみました。
整理しますと自分の疑問点は結局以下に集約されます。
①[改ページ]コントロールのVisibleプロパティをFalseにする理由
②[改ページ]コントロールに関する設定を、ページヘッダーセクションに記述する理由
③[カウント]テキストボックスの値を0にする理由
④[カウント]テキストボックスの設定を、ページヘッダーセクションに記述する理由
①をTrueに設定してみました。確かにレコード毎に改行されてしまいました。だからFalseに設定する。ただ、この記述自体、Me.改ページ.Visible = Falseを無くしてしまっても問題無く動作します(10行毎にちゃんと改行される)。にも関わらず、わざわざ書く理由は可読性を考慮しているからなのですかね?
②に関しては、詳細セクションに記述してもきちんと動作しました。ただ、
との事ですから、レコードの数だけVisible = Falseを設定することになり、明らかに冗長な処理となることから、ページ毎に1回だけイベントが発生するページヘッダーセクションに記述するのが合理的という解釈で良いのですかね?
③に関しては、Me.カウント.Value = 0をコメントアウトすると、改行がされませんでした。イミディエイトウィンドウで値を確認してみるとNull値が入ってしまいカウントアップが働いていませんでした。なので初期化は必須ということが分かりました。ただ、この手の変数の設定は初期化を省略した場合、自動的に0が設定されて問題無く動くような気がしたのですが、この認識自体間違いですかね?例えば、以下のコードだと0が返ります。
④は、詳細セクションに記述してしまうとレコード毎に毎回最初に0がセットされてしまい、カウントが1以上から先に進まないことが確認できました。故にページヘッダーセクションに記述する必要があると理解出来ました。
以上より、①~③はまだ少しモヤモヤしています。ご回答いただけると幸いです。
hirotonさん
丁寧に解説ありがとうございました。
こんばんは。
起動.mdb作成してみました。
autoexecでverのチェック、アップデートなどはうまくいきました。
そこで問題があったのですが、
MSACCESS.EXEのパスが一定ではなく、
もちろん私と同じフォルダ名の人以外は動きませんでした…
各pcのMSACCESS.EXEのパスを取得して、起動できるのでしょうか?
下記がshellの部分です。
「代替の背景色」とは何ぞや?という話なんですが、英語でプロパティ名をみると「Alternatebackcolor」となってます。「Alternate」には「代わりの~」という意味があるのでそれをもって「代替の背景色」と日本語を充てることはできますが、「交互の~、1つおきの~」という意味を使うべき案件ですね。つまり「偶数行の背景色」を設定するプロパティなわけです。
結果からしたら認識されている通りで構わないんですが、偶数行なら通常の背景色(BackColor)よりも代替の背景色が優先されるので「[代替の背景色]に、「#FFFFFF」が設定されて」いるとVBAであろうとなかろうとBackColorを変更しても影響が出ない状態になってるよ、ということです。
VBAの命令「
Me.詳細.BackColor =
」は実際に色を塗る作業をしているわけではありません。背景色プロパティの値を変えているだけだと理解できると「じゃあ、実際に色を塗るタイミングでは何が起きているのか(偶数行だから代替の背景色が使われているな)」とつながると思います。その教材はみたことないのでコードからの推測です。
プレビュー時でも印刷時でもグループヘッダーは出力されませんね。
何のためにしているのかはわかりません。グループヘッダーの「可視」プロパティを「いいえ」にしても同じことのような気がします。
詳細セクションの[改ページ]コントロールがTrueだとレコード毎(1行毎)に改ページされてしまうからです。
これらのコードでやっていることは、10レコード(10行)毎に改ページするということだと推測します。
(教材に目的が書いてありますよね。)
下記の点を理解することが必要ですね。
ページヘッダーセクションのフォーマット時イベントはページが出力される一番最初に1回発生してヘッダーを出力する。
詳細セクションのフォーマット時イベントはレコード毎に発生して1行分出力する。
つまり、
最初にページヘッダーのフォーマット時イベントが発生してヘッダーが出力される。
そのときに、改ページを非表示にして1行毎に改ページしないようにする。
「カウント」テキストボックスは現在1ページ内で何行目かを取得するものなのでまずは初期化しておくす。
詳細セクションのフォーマット時で「カウント」の数値にプラス1をする。これによって現在、1ページ内で何行目を出力するのが分かる。
その数値が10なら10行目ということなので、改ページを表示させることで改ページして次のページに移動する。
ということです。
⑤に関してはその理解であってます。
レポートのイベントの発生メカニズムはかなり複雑です。
下記がその理解を深めるのに役立つと思いますので一度目を通しておくことをお勧めします。
レポートのイベントの発生メカニズムの研究 - hatena chips
レポートのイベントの発生メカニズムの研究 その2 - hatena chips
そういうことです。
mdbなら32ビットでも64ビットでも問題ないと思います。
ただ、実際にやったことはないので何か想定外の問題があるかも知れません。
とりあえずやってみてはどうでしょうか。
よく考えたら、列の表示/非表示はVBAで制御できますので可能ですね。
■T'sWare Access Tips #562 ~データシートフォームの列の表示/非表示を個別に切り替えるには?~
ただ、データシート表示なら、列固定ができますので、常に表示したい列は固定しておいて、あとはスクロールさせるという方法で対処できるので、それほど必要性はないと思います。
適当にためしてみたら、たまたま当たっていたようで自己解決しました。
=[リスト名].Column←列数を入れる。
すみません。ありがとうございました。
コントロール(コントロールソース)の理解があやふやな感じですねぇ
コントロールはコントロールソースの設定によって3種類の動作をします
1.コントロールソースにフォームのレコードソースのフィールドを指定する
指定したレコードソースのフィールドそのものにリンクされます。
現在のレコードの(指定したフィールドの)値が表示され、このコントロールを更新するとデータが書き換わります。
(フィールドがクエリの計算式などの場合、編集不可だったりもします)
2.コントロールソースに計算式を指定する
計算式に従った結果が表示されます。
編集不可です。このコントロールが直接データを書き換えることはありません。
3.コントロールソースに非連結を指定する
フォーム上で任意で編集ができるコントロールです。
このコントロールが直接データを書き換えることはありません。
今回の例のように、表示したい個人IDを入力したり、検索用のキーワードを入力するテキストボックスを設置するときに使います。
非連結のコントロールは、ユーザーが一時的に使いたいデータを入力するためのコントロールとなります。
また、上記はコントロールの値(value)に関する話で、いろいろな制御にかかわる各種プロパティは、別物です
これの第4引数(
"個人ID=" & Me.PF_CMB_個人ID.Value
)はフォームのFilterプロパティに値を設定する指定です。これ自体は何かデータを書き換えるようなことはしません。(コントロールに値を設定するようなこともありません)
サブフォームのデータを絞り込むときには
としました。今回はフォームが別になるので、同様に考えるなら
とすることができます。
ただし、フォームを新たに開くなら、hatenaさん提示のように同時に設定できるので
とできます。
同じことをしているとわかれば、個人IDを直接変更しているものではないとわかると思います。
各コントロールは、処理毎に、冒頭のコントロールのルールに従って内容を再表示します。
レコードの絞り込みの結果、現在のレコードが変更になれば、変更後のレコードの値を表示しなおします。
Excel的に言えば、見ている行が変わったというだけでデータそのものが変わったわけではありません。行が変わったので、その行の値をそれぞれ表示しなおしているだけです。
そうですよね。ありがとうございました。
おはようございます、ろでますです。
大変ありがとうございます、思った通りの動作ができました。
ちゃんと理解していれば、こんなスマートに書けるものなんですね。
DoCmd.OpenForm "ユーザー情報編集フォーム", , , "個人ID=" & Me.PF_CMB_個人ID.Value
で、対象のフォームのコントロールに、こういった形での引数渡しができることをはじめて知りました。
これだと、コントロールに値が入るので、他のコントロールも連動して変わってくれるという訳ですね。
また、
Forms!ポップアップ入力!PF_CMB_個人ID.Requery
Forms!ポップアップ入力!PF_CMB_個人ID.Value = Null
で、コントロール単位にReaueyできること教えていただきました。
大変良い勉強になりました、ありがとうございました。
営業日報テーブルをレコードソースとするレポートをメインレポートにして、
訪問先テーブル、休憩テーブルからそれぞれレポートを作成して、サブレポートとして埋め込む設計にすればいいでしょう。
サブレポートの罫線は下記の方法で。
レコードがない場合も用紙の最後まで罫線を出力する - hatena chips
帳票フォームで表示項目が多いとき、ページ切り替えで - hatena chips
上記のページのタブのことでしょうか。
だとしたら、不可能ですね。
「ポップアップ入力」は閲覧用なら、不用意な編集、削除ができないように、フォームの「レコードセット」プロパティを「スナップショット」に設定しておくといいでしょう。
あと「UC_個人ID」テキストボックスか非連結になってますが、コントロールソースを「個人ID」に設定しましょう。
"ユーザー情報編集フォーム"の「追加の許可」は「いいえ」にしておくといいでしょう。「はい」にしておくなんかの表示に新規レコードへ移動してしまう恐れがあります。
あと、「フィルターの使用」は「いいえ」に設定します。これをしておかないと、せっかく対象レコードのみ抽出されているのか、フィルターを解除されて全レコードが表示されてしまう恐れがあります。
とりあえずはそのファイルで状況は把握できます。
コンボボックスのリストに #DELETED が表示される現象の解決法は、コンボボックスを再クエリすればOKです。
ただし、致命的な欠陥かあります。
「ポップアップ入力」のコンボボックスで後の方のレコードを選択してからボタンクリックで「ユーザー情報編集フォーム」を表示させると、テーブルの先頭のレコードが、コンボボックスで選択したレコードで上書きされてしまいます。
「ユーザー情報編集フォーム」を開いた直後は先頭レコードが表示されます。ところが、読み込み時イベント Form_Load() で「ポップアップ入力」のデータで上書きしてしまってます。
Form_Load()のコードは削除してください。
それから、「ポップアップ入力」のコマンドボタンクリック時のコードを下記に変更してください。
これで、"ユーザー情報編集フォーム" のレコードは、「ポップアップ入力」と同じものになります。
再度の質問よろしくおねがいします
質問前にそちらは拝見させていただきましたが
ネットで探した画像を貼ったこともありうまく伝えられませんでした
実際には下記のようなレイアウトになっております
画像にありますように
日付と氏名、車両点検項目をメインである営業日報テーブル
訪問先を訪問先テーブル
休憩を休憩テーブルに、親子関係で入力します
(それぞれ別途主キーなどは用意してあります)
上下に2つ表組みがあるので単純に固定行にしたのでは対応できないのではないか、と困っていました
「詳細」のレコードが並ぶところが2ついるようになるのではないかと
今やっているEXCELでは画像の表に直接入力してVBAを使い別のシートのセルに転記
印刷時に再度転記しております
このような場合フォームにサブフォームを表示させ印刷するものでしょうか?
こんばんわ、ろでますです。
簡素化せず、ごちゃごちゃな物を送付しては失礼とおもいましたので、必要な部分のみを切り出しました結果、シンプルなフォームにしてしましました。その辺のご説明ができてなくて申し訳ございません。
おっしゃる通りで、ポップアップ入力は個人データ閲覧用として、ユーザー情報編集フォームはデータ入力/編集/削除用にして、不用意な削除をできないようにしています。
簡素化するにあたり、消したところがあります。
各人のもつ、障害状況(身体障害であったり精神障害であたったり)も、メインのフォームで見れるようにしており、それらも別フォームで個別に編集できるようにしているため、分けた方が分かりやすいと判断してわけました。
もしよろしければ、そのフォームだけでも見ていただけましたら、状況を把握していただけるとおもうのですが、よろしいでしょうか・・・。(ユーザー追加などは未完成です)
先走ってすいませんが、そのファイルをアップロードさせていただきます。
内容が中途半端で申し訳ありません。
バックエンド2つを同時に開く事はありません。
今回2個目に作成したVBSは、先程のとは別のものです。
こちらはバックエンド一つ、フロントエンドの運用です。
先程書いた1つ目(フロントエンド+バックエンド2つ)の起動用のmdbと2つ目(フロントエンド+バックエンド)の起動用のmdbをそれぞれ作成する、またmdbで起動であれば、bit数の問題もクリアできる、という理解であっていますでしょうか?
何度も申し訳ありません。
サンプルファイルを拝見しました。
「ポップアップ入力」フォームと「ユーザー情報編集フォーム」はほぼおなじ構成ですが、2つに分ける目的はなんでしょうか。
「ポップアップ入力」はデータの閲覧用(ここで更新や削除はしない)、
更新や削除は「ユーザー情報編集フォーム」で行う、ということでしょうか。
閲覧時に不用意に、更新したり削除してしまわないようにするというのが目的でしょうか。
こんばんわ、ろでまです。
すいません、今気づきました。
簡素化するあまり、リレーショナル部分も切ってしまってました。
ただ状況は同じで、ポップアップサブフォームで基礎データ部分を削除すると、メインフォームのコンボボックスで#DELETEDが表示されてしまします。
送付していただいたサンプルファイル
現状のデータベースファイルはフロントエンド(アプリケーション)とバックエンド(データ)に分割しているということですよね。
で、データ量が多いので、バックエンドを最近のものと過去のものに分割している。
通常はフロントエンドに最近のバックエンドからデータをコピーして運用している。場合によっては過去のバックエンドからコピーしてくる。
そのような運用ならフロントエンドは一つでいいと思いますが、なぜ、2つ同時に開く必要があるのでしょうか。
ありがとうございます。
元々私の作り方がいけなかったのか、
元データがあるmdbが2種類あります。
それはデータ量が多かったので、一定の期間で区切ったものです。比較的最近のものが①、過去のものが②とします。
元データ①の片方には毎月数万件追加されます。
フロントエンドのmdbは、社員IDでログインすると、データ追加時に所属拠点の分の一定テーブルデータをコピーしてくるようにしています。
期間外の過去の時は②からコピーしています。
ただし、年度更新の時や何か機能を追加した時はVBAを書き換えて、空のフロントエンドmdbを置いて、access自体をしてコピーさせています。
ここで使っているVBSをmdbで、という事ですよね?VBSを2個使用していたので、起動用のmdbも2個で、32bitと64bitは気にしなくてもいい、という事でましょうか?
ちなみに以前はフロントエンドのmdbをいちいち配布していたのですが、どうにも差し替えを忘れる方がいて、強制コピーしてくるように、こちらのVBSにたどり着いた次第です。
会社のpcからはこの掲示板に繋がらないので、ファイルを送れません(自分の携帯から見ています)見て頂く事も出来ないので、うまく伝わればいいのですが…長々とすみません。
下記のページが参考になると思います。
レコードがない場合も用紙の最後まで罫線を出力する - hatena chips
明細を持つ伝票とその複写を同じページに2分割して表示する - hatena chips
これを参考に試してみて、分からない部分があれば質問してください。
2003なら、MDBファイルを作成してそこから、DAOで更新テーブルをチェックして更新があったら FileCopy、Shell関数でMDBファイルを開いて、自分自身を閉じる、というVBAコードを起動時フォームに記述するという設計にするのが簡単かと。
テスト等、色々ありがとうございます。
お手数をおかけして、すみません。
やはりタスクバーに入れるとダメなんですね…
社内で基幹システムの補助ソフトとして、accessを使用しています。
その為なのか、会社は新しいaccessを購入してくれないようです。それで2003を使用している状態です。
書くのを忘れてましたが、基本的に私のpc以外はランタイム環境です。
VB.Net…勉強してみます。ソフトが入っていないかもしれませんが、visual studio communityからダウンロードしてみます(色々あって少々戸惑いながらやっていますが)
こんにちわ、ろでますです。
たびたびのご厚意ありがとうございます。
簡素化したファイルをアップロードさせていただきます。
フォームは最初に出てくるポップアップフォームと、「削除フォームへ」と押せるボタンから出てくるポップアップフォームだけになっています。
よろしくお願い申し上げます。
ごめんなさい、解決しました。文字が長すぎます、とエラーメッセージが出たりしたと思うのですが、その後コントロール名に記号を使っていたのを除いたらなおりました。
Requeryはコンボボックスに対してしていたのですが、
その後原因?がわかりました。
現在下記のソースを使っていました。
Private Sub Tab1_Change()
Me.Tab2.Pages(Me.Tab1).SetFocus
End Sub
しかし、下記のソースに差し替えたところ、うまくいくようになりました。
Private Sub Tab1_Change()
Me.Tab2 = Me.Tab1
End Sub
勘違い?かもしれませんが、一応ご報告でした。
ご教示、ありがとうございました。
明快な回答ありがとうございました。
勘違いしてました。
コンボボックスの入力チェックプロパティ
ComboBox の "LimitToList/入力チェック" プロパティ (Access)
コンボボックスの値リストの編集の許可プロパティ
ComboBox. AllowValueListEdits プロパティ (Access)
一つのデータベースファイルをタスクバーに最小化すると、症状がでるのを確認しました。
ちょっと解決策はわかりませんね。
複数起動したい場合は、VBSではなく、VB.Net か Accdb で同様の機能を作成する方向で検討したほうかいいかもしれません。