Private Sub txt日付_AfterUpdate()
If IsDate(Me.txt日付.Value) Then
Me.Filter = "日付=#" & Me.txt日付.Value & "#"
Me.FilterOn = True
If Me.Recordset.RecordCount = 0 Then
Me.日付.DefaultValue = "=#" & Me.txt日付.Value & "#"
Me.AllowAdditions = True
End If
Me.項目1.SetFocus
End If
End Sub
フォームの挿入後処理のイベントプロシージャを下記のように記述します。
Private Sub Form_AfterInsert()
Me.AllowAdditions = False
End Sub
SELECT "(すべて)" AS 年月
FROM T_案件
UNION SELECT 年月
FROM T_案件;
'年月選択 更新後処理
Private Sub cbo年月_AfterUpdate()
If Me.cbo年月 = "" Then
Me.Filter = ""
Me.FilterOn = True
Else
Me.Filter = "年月=" & Me.cbo年月
Me.FilterOn = True
End If
End Sub
Private Sub テキスト5_Enter()
Me.テキスト5.Height = Me.テキスト5.Height * 2 '高さを2倍に
End Sub
Private Sub テキスト5_Exit(Cancel As Integer)
Me.テキスト5.Height = Me.テキスト5.Height / 2 '高さを元に戻す
End Sub
Set rs1 = db.OpenRecordset (strSQL, dbOpendynaset, dbDenyWrite, dbPessimistic)
の行です。
エラーメッセージは下記のとおりです。
Run-time error '3008'
The table'M_F_ID' is already opened exclusively by another user, or it is already open through the user interface and cannot manipulated programmatically.
cmbF_IDがあり、Property SheetにてRow Sourceを
Select Right([FV_ID],Len([FV_ID])-5)
From MT F_ID
Group By Right([FV_ID],Len([FV_ID])-5)
としています。
ボタンbtn001を押すイベント内で
テキストボックスの入力状態の確認がなされた後、
If fncUpdateMasterTables = False then Exit sub
End If
があって、関数で更新処理を行います。
Private Function fncUpdateMasterTables() As Boolean
On Error GoTo ErrorHandler
Dim ws As DAO.Workspace
Dim db as DAO.Database
Dim rs1 as DAO.Recordset
(変数宣言中略)
DoCmd.Hourglass True
Set ws = DBEngine.Workspaces(0)
Set db = CurrentDb
【VBA】すみません・・修正しました。
Private Sub cbo年月_AfterUpdate()
If Me.cbo年月 = "(空欄)" Then
Me.Filter = "年月 Is Null"
Me.FilterOn = True
Else
Me.Filter = "年月 ='" & Me!cbo年月 & "'"
Me.FilterOn = True
End If
End Sub
★残り問題点
①(空欄)が選択肢の一番下に表示されるのを一番上に持ってきたい
②選択肢の中に空のものがあるのを表示しないようにしたい。
現状のファイルを送信フォームから送ってもらった方が速そうです。
修正しました!
しかし、まだ問題点が残っています。
①年月がなぜか選べなくなった。(選択すると表示されるレコードが0になる)
②(空欄)の選択肢を一番上に持ってくる方法がわからない。
【VBA】
Private Sub cbo年月_AfterUpdate()
If Me.cbo年月 = "(空欄)" Then
Me.Filter = ""
Me.FilterOn = True
Else
Me.Filter = "年月=" & Me.cbo年月
Me.FilterOn = True
End If
End Sub
【値集合ソース】
SELECT DISTINCT "(空欄)" AS 年月
FROM T_案件
WHERE (((T_案件.年月) Is Null))
UNION SELECT DISTINCT 年月
FROM T_案件
ORDER BY 年月 DESC;
★下記のVBAにすると、きちんと絞り込み表示ができます。
Private Sub cbo年月_Click()
DoCmd.SetFilter "", "[年月] Like [Forms]![F_案件]![cbo年月]", ""
End Sub
いろいろ方法はありますが、一例を紹介しておきます。
フォームウィザードで入力したいテーブルをもとに単票フォームを作成します。
フォームプロパティを下記のように設定します。
「日付」のテキストボックスの「使用可能」は「いいえ」にします。
フォームヘッダーにテキストボックスを配置して下記のように設定します。
txt日付 の更新後処理のイベントプロシージャを下記のように記述します。
フォームの挿入後処理のイベントプロシージャを下記のように記述します。
以上です。
同じでも、分けても、どちらでもOKです。
労基などに提出する統一された出勤簿が同じ欄なら同じで、異なる欄なら別に、というように用途に合わせて使いやすいように設計すればいいでしょう。
テーブルを分けない場合
開始点呼時間 終了点呼時間 と
出勤時間 退勤時間 を
それぞれ同じフィールドにするということですか?
とりあえずコードは下記に修正してみてください。
修正前のコードだとテーブル名やフィールド名に空白や記号が含まれるとエラーになる場合がありますので、その対策を追加しました。
それてもエラーになるなら、この関数を呼び出す前後のコードを提示してください。
上記は、値集合ソースとvbaに入力しているものです。
詳しいご解説ありがとうございます。コントロールソースを指定しておりませんでした。大変お手数をおかけいたしました。うまくいきました!ありがとうございます。
下記作成しましたが、何を選択してもなにも表示されない状態になりました。
また、コンボボックス内に空白の選択肢ができてしまいます。
SELECT "(すべて)" AS 年月
FROM T_案件
UNION SELECT 年月
FROM T_案件;
'年月選択 更新後処理
Private Sub cbo年月_AfterUpdate()
If Me.cbo年月 = "" Then
Me.Filter = ""
Me.FilterOn = True
Else
Me.Filter = "年月=" & Me.cbo年月
Me.FilterOn = True
End If
End Sub
「cbo種類」はフォーム上のコントロールの名前で、コントロールソース名とは別ですか?
カウントに使えるフィールドはレコードソースのフィールドなので、cbo種類のコントロールソース名を指定してあげてください
条件判断についても実際のデータに対して行うので、コンボボックスで目に見える表示と連結列が異なる場合は連結列の値で条件判断をしてあげる必要があります。「特別」や「通常」が直接テーブルに保存される値ならそのままで大丈夫です
追加で試された「
=Count(IIf([txt価格]="1,000",1))
」は「=Count(IIf([価格]=1000,1))
」のような形なら動くと思いますあ・・わかりました、
上記SQLをcbo年月に入れて、下記をVBAに入れています。
これが、②に対応できていないんですね・・もう少し考えてみます。
Private Sub cbo年月_Click()
DoCmd.SetFilter "", "[年月] Like [Forms]![F_案件]![cbo年月]", ""
End Sub
テキストボックスに上記式を入れたのですが、「#エラー」と表示されます。
ためしに「=Count(IIf([txt価格]="1,000",1))」など、他のフィールドでも試してみたのですが、「#エラー」と出ました…。何か原因になりうるものがありますでしょうか。
こちらの件、ずっと解決できず課題になっていました。
下記sqlを作ったのですが、うまくいきません…なぜでしょうか…
①元のデータが降順にならない。
②すべてが表示されない。
SELECT DISTINCT T_案件.年月
FROM T_案件
ORDER BY T_案件.年月 DESC
UNION
SELECT "(すべて)" AS 案件NO FROM T_案件;
ありがとうございます!のちほど試してみます!
どのように表示したいですか?
フォームで見えてる分だけで集計したいならCount()関数で
Count()関数は、指定したフィールドの「Null」のデータをカウントしないのでIIf()関数を使って数えたいものだけデータを出力するようにすればそれぞれで件数を出すことはできます
ex)
大変参考になりました。クエリの件も、見直してみたいと思います。ありがとうございました。
人それぞれの考え方があると思いますが、私は結合するフィールド同士は同じ名前にしています。
クエリにするとき、通常は、一対多の関係のテーブルを結合しますが、クエリに表示させるのは、多側のフィールドにします。
それを両方表示させたり、* で全フィールドを表示させたりすると、同じ名前のフィールドが存在するので、コントロールソースなどで参照するとエラーになります。
ですので、両方表示させることがないように設計すれば問題ないです。
もし、両方表示させる必要がある場合(通常はないですが)は、片方のフィールドに別名を付ければ問題ないです。
ということなら、hirotontさんも言われてますか、そもそも分ける必要がないと思います。
その統一された書式でテーブルを作成して(両方に必要なフィールドをすべて持たせる)、そこに入力していけばいいのでは。
あとは、運転日報かどうかを識別するフィールド(Yes/No型)を追加して、運転日報のみ必要な時に、そのフィールドで抽出をかければいいだけです。
レポート上のコントロールの位置やサイズ、フォントサイズが、レポート上の描画システムと、プリンタードライバーで、解釈に誤差があるのが原因だと思います。
ということで、デザインビューだけでなく、プレビューで結果を確認して、微調整する必要があります。
プリンタードライバーによっても微妙に異なる場合があるので、ある程度余裕をもってサイズや位置を設定する必要もあると思います。
画面上の結果と、印刷結果が異なるのは他のソフトでもありがちです。特にエクセルなんかは、Accessよりひどいです。
たくさんのご回答ありがとうございました。
問題の箇所になっているところの必要性も考え、別の方法で回避します。
運転日報の入力にフォームを使っているのであれば、フォームの挿入後処理が使えるので、追加クエリを発行すればいいと思います
が、単純にコピーするだけでいいのであればデータを2重で持つ意味はないのでコピーではなくユニオンクエリで必要なタイミングでデータを連結すればいいと思います
そもそもの話、同じ形式のデータになっているのであれば運転日報テーブルと出勤簿テーブルに分ける必要があるのかが疑問ですが
お世話になります。
文字を入力する時だけ、下記のように指定するように設定しました。
Me.テキスト114.Height = 1600
ありがとうございました。
お世話になります。
早速ありがとうございました。
後ほど、確認と報告をさせて頂きます。
うまくいきました!ありがとうございました🙇♂️
たぶん
かな?
DJoin関数を導入して、
https://web.archive.org/web/20150517052733/http://www.f3.dion.ne.jp/~element/msaccess/AcTipsVbaDJoin.html
コンボボックスのフォーカス取得時(?)に、
Me.cmbF_ID.RowSourceType = "Value List"
Me.cmbF_ID.RowSource = DJoin("Right([FV_ID],Len([FV_ID])-5)", "MT_F_ID", , , ";", True)
としては、いかがでしょうか。
もし、本当にコンボボックスの「値集合ソース」プロパティにクエリを設定しない場合はエラーがでないのなら、
「値集合タイプ」を「値リスト」に設定して、
db.OpenRecordset(strSQL, dbOpenSnapshot) という感じでレコードセットを開いて、ループさせて AddItem でリストを追加すればどうでしょうか。
コンボボックスの「値集合ソース」プロパティにクエリ名を設定しているということでしょうか。
(コンボボックスにレコードソースはない)
原理的に考えて、コンボボックスの値集合ソースの設定で、排他エラーがでるとは考えにくいです。
他にそのテーブルと連結しているテーブルとか、更新クエリを実行しているとか、別の処理で排他的に開いているとか、、、
があるとしか思えません。
提示されている情報からは、これ以上のアドバイスは無理です。
レコードソースは空欄です
更新はないと思います。MT_F_ID(M_F_IDは誤植でした)については
コンボボックスcmbVerのイベントがあって、一度参照しています。
Private Sub cmbVer BeforeUpdate(Cancel as integer)
(前略)
strSQL = "SELECT * FROM[MT_F_ID]" & _
"WHERE [FV_ID] = '" & Me.txtFV_ID & "'"
SET rs1 = db.OpenRecordset(strSQL, dbOpenSnapshot)
With rs1
If .EOF then
(以下レコードがない場合はExit sub、
ある場合は、非連結テキストボックスに対して、
Me.txtPCardDate=.Fields("PCard_date")とデータを入れただけ)
コンボボックスcmbF_IDのレコードソースにMT_F_ID関連のクエリを組み込んでいないときはエラーが出ませんので、それ以外の部分で更新の影響が出ていることはないと(勝手に)考えております。
マウスクリックより、フォーカス取得時とフォーカス喪失時に設定するのがいいと思います。
フォームのレコードソースが、M_F_ID またはそれを含むクエリになってませんか。
あるいは、提示のコード以外の部分で、M_F_ID を更新するような操作を行ってませんか。
Set rs1 = db.OpenRecordset (strSQL, dbOpendynaset, dbDenyWrite, dbPessimistic)
の行です。
エラーメッセージは下記のとおりです。
Run-time error '3008'
The table'M_F_ID' is already opened exclusively by another user, or it is already open through the user interface and cannot manipulated programmatically.
On Error GoTo ErrorHandler
の行をコメントアウトして実行してみると、どの行でエラーがでますか。
また、その時の、エラーメッセージも提示してください。
そうだとうれしいです。お言葉ありがとうございます!
Access英語版です。
cmbF_IDがあり、Property SheetにてRow Sourceを
Select Right([FV_ID],Len([FV_ID])-5)
From MT F_ID
Group By Right([FV_ID],Len([FV_ID])-5)
としています。
ボタンbtn001を押すイベント内で
テキストボックスの入力状態の確認がなされた後、
If fncUpdateMasterTables = False then Exit sub
End If
があって、関数で更新処理を行います。
Private Function fncUpdateMasterTables() As Boolean
On Error GoTo ErrorHandler
Dim ws As DAO.Workspace
Dim db as DAO.Database
Dim rs1 as DAO.Recordset
(変数宣言中略)
DoCmd.Hourglass True
Set ws = DBEngine.Workspaces(0)
Set db = CurrentDb
strSQL = "SELECT * FROM[MT_F_ID]" & _
"WHERE [FV_ID] = '" & Me.txtFV_ID & "'"
Set rs1 = db.OpenRecordset (strSQL, dbOpendynaset, dbDenyWrite, dbPessimistic)
中略(レコードセットrs2を参照した後、フォーム内のデータをrs1とrs2で更新)
ErrorHandler:
DoCmd.Hourglass False
Msgbox Err.number & ": " & Err.Description,vbcritical, _
"Running Error(" & Me.Name & .fncUpdateMasterTables)"
Resume Exit_fncUpdateMasterTables
End Function
以上です。よろしくお願いいたします
Format関数についてもご解説いただき、よく理解できました。今後も活用していきたいと思います!貴重な知識を、ありがとうございました。
>MSのドキュメントを読んで一発で理解できことは稀です。一応読んでみて、実際にやってみて理解するという繰り返しですね。
MSのドキュメントは理解できなかったため、今までwebの検索結果からMSのドキュメントは、ほぼ避けて通ってきました。検索結果から、他の方のブログ等を参考にするようにしてきました。
hatenaさんのアドバイスに気づかされました。今後はMSのドキュメントをもっと理解する努力をしていきたいと思います。(とは言いつつ今後も質問させていただくことが多いかと思います…申し訳ありません。宜しくお願いいたします。)
あっ、そうでした。DCountはNullはカウントしないのでした。
すぐ、それに気づいたということは、cerophanさん、確実にスキルアップしてますね。
Format関数の設定は、書式プロパティの設定と同じですので、理解しておくと応用が効きます。
"\,&" ですが、コピーしてVBEとか書式プロパティに貼り付けると "¥,&" となります。(ブラウザ上では¥ は \ に変換されるので)
紛らわしいのでいちおう理解しておいてください。
書式プロパティの設定(=Format関数の設定)では、¥ の後に記述したテキストはそのまま表示されます。
例えば日付などは、
yyyy¥年mm¥月dd¥日 と設定しますよね。¥ の後の年、月、日 はそのまま表示されます。
¥, とするとカンマがそのまま表示されます。 & の箇所にはフィールドのテキストが表示されます。
書式は ; でセクションを2つにわけることができて、
一番目のセクションにテキストがある場合の書式を設定して、
2番目に長さ 0 の文字列か Null値のフィールドの書式を設定します。
2番目のセクションを省略した場合は、テキストがないとき("" または Null)の時は何も表示されません。
¥,& という設定は、テキストがあれば、テキストの前にカンマ、テキストがない(""またはNull)の時は何も表示しないという意味になります。
テキストフィールドの書式を設定する - Access
MSのドキュメントは非常に分かりにくいので、一応読んで実際にいろいろ設定してみて結果を確認して初めてそういうことを言っているかと理解できます。
MSのドキュメントを読んで一発で理解できことは稀です。一応読んでみて、実際にやってみて理解するという繰り返しですね。