ublic Sub SetSchedule()
Dim i As Integer, rs As DAO.Recordset
For i = 1 To 42
Me("T" & i).Caption = ""
Next
Set rs = CurrentDb.OpenRecordset( _
"SELECT 日付, 時刻, 略, 氏名 FROM T予定 WHERE " &
"日付>#" & FirstDay & "# AND 日付<=#" & FirstDay + 42 & "# ORDER BY
時刻", _
dbOpenForwardOnly, dbReadOnly)
Do Until rs.EOF
With Me("T" & rs!日付 - FirstDay)
.Caption = .Caption & Format(rs!時刻, "hh:nn") & " " & rs!略 &
rs!氏名 & vbCrLf
If Me(rs!略).Value = "関" Then
Me(rs!略 & rs!氏名).ForeColor = 8388608
Else
Me(rs!略 & rs!氏名).ForeColor = 0
End If
End With
rs.MoveNext
Loop
rs.Close: Set rs = Nothing
End Sub
一度差し込み設定をしたWord文書を作成したら、差し込み印刷の開始→標準の Word 文書でデータのリンクを解除して保存しなおします(開いてもダイアログの出ない文書にする)
都度ACCESS VBAからWord文書を開く→データソースのリンクをします
Dim wordFilePath As String
Dim objWord As Object
Dim objDoc As Object
wordFilePath = "C:\データ\さしこみ.docx"
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set objDoc = objWord.Documents.Open(wordFilePath)
Dim accessFilePath As String
Dim strConnection As String
Dim strSQL As String
accessFilePath = Application.CurrentProject.FullName
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & accessFilePath & ";"
strSQL = "SELECT * FROM `qさしこみ用`"
With objDoc.MailMerge
.OpenDataSource _
Name:=accessFilePath, _
LinkToSource:=True, _
Connection:=strConnection, _
SQLStatement:=strSQL
.ViewMailMergeFieldCodes = False
End With
Set objDoc = Nothing
Set objWord = Nothing
なるほど、やはりそうですよね。。。Accessを勉強し始めた頃、将来データ量が増えすぎることを恐れて、カテゴリのちがうDBをそれぞれに分けて作ってしまったんですが、それがそもそもの間違いだったんですね。
統合するとシステム全体を見直さないといけないので、時間がかかりますがコツコツやってみます。
いつも本当に勉強になります。ありがとうございます!
テーブルでのプロパティ設定のみですので、VBAでコード書くよりよほどハードルは低いと思いますので、とりあえずチャレンジしてみてください。
まったく同じフィールドを持っているテーブルを分けるのはデータベース的にはNGな設計になります。一つのテーブルにまとめるべきです。
例えば、A-1とA-2が全く同じフィールドなら、一つのテーブルにして、2つを識別するフィールドを追加します。
A-1とA-2の主キーが重複するなら、識別フィールドと現状の主キーの複合主キーにします。
B-1、B-2、B-3、B-4に関しても同様に一つのテーブルにまとめます。
そうすれば、クエリは一つですみます。あとは、それぞれの識別フィールドに抽出条件を設定すれば希望のデータを取り出せます。
レポートなら開くときにOpenReportメソッドの引数で抽出条件を設定することができます。
ありがとうございます。
まだまだ勉強中の私にはハードルが高そうすが、チャレンジしてみます。
いつもありがとうございます。本当に勉強になります。
>> 3
凄いです。正直、使い道がないプロパティと思っていました。
よく見たら、ラベルでしたね。ラベルの中身をカラフルに、色やフォントを変える文字列関数ってありましたっけ、誰かフォローして下さい。
視認性に拘るなら、略のラベルと氏名のラベルを同じように用意して最初から作りましょう。
視認性よりも可読性・保守性が大事だと思います。明日、明後日、来週、来月、来年、5年、10年後に見たときに、パッと理解・説明出来ないなら無意味ですよ。
Exitイベントでの入力チェックは完全ではありません。
例えば、先頭のテキストボックスから順に移動しながら入力してくれればいいですが、マウスで別のテキストボックスをクリックして、そのテキストボックスをとばした場合はチェックができません。
分割フォームでもフォーカス移動関係は複雑になるので、うまくいかないこともあるでしょう。
入力チェックを確実にするならやはりテーブルの方で設定するのがいいと思います。
エラーメッセージを希望のものにしたいなら、
テーブルやフィールドの「入力規則」プロパティと「エラーメッセージ」プロパティを使って入力チェックするといいでしょう。
入力必須にしたいフィールドがテキスト型なら、
そのフィールドプロパティを下記のように設定します。
以上でテーブルレベルで入力必須にできます。
ForeColorというのは「前景色」プロパティです。「前景色」プロパティはテキストボックスのプロパティです。
rs!略 & rs!氏名
は、レコードセットの「略」フィールド、「氏名」フィールドに入っているデータです。Me(rs!略 & rs!氏名)
としたら、そのデータと同じ名前のテキストボックスを探すことになりますが、そのような名前のテキストボックスはないですよね。まずは、それぞれのコードの意味を理解するように努力してください。最初は難しいと思いますが、それをしないとスキルアップはしません。
とりあえず、
With Me("T" & rs!日付 - FirstDay)
の部分でテキストボックスを指定しています。
With
の意味も調べてみてください。ちら見回答であれですが、上手く出来ないなら、2つに分ければいいんじゃない。略の前景色は、ほにゃらら、氏名の前景色は、ほにゃらら、みたいに。
文字色がレコードに保存されているならリッチテキスト形式を使うと楽ができるかもしれません
標準モジュールに次の関数を追加する(※)
新たにテキストボックスを設置する
このテキストボックスは編集できないので、編集が必要なら元のテキストボックスにぴったり重ね合わせて(前面配置にする)フォーカス取得時に
Me!項目.setFocus
とかしてあげる必要があります(※)単純な計算なので関数を使わず直接コントロールソースで計算させることもできます
当方、Access2016で同じエラー解決しました。
条件付き書式のスペースを消すとエラーが出なくなりませんか。
NG: "[文字色] = " & Rs!文字色
OK: "[文字色]=" & Rs!文字色
これは以下2点において、Access2016のバグと言っていいと思います。
・条件付き書式の解析の問題
・エラー内容とメッセージが違う問題
ありがとうございます。できました。
もうひとつご相談です。対象のフォームが分割フォームで作成されているのですが、新規レコードのフィールドAに入力しないまま、データシートビューで別のレコードをクリックすると、フォーカスは教えて頂いたVBAでそこから移動しないのですが、単票フォームはクリックしたレコードに移ってしまいます。それも抑止する方法はないでしょうか?
何度もすみません。
hatena様
お手数をおかけいたします。
If rs!略.Value = "関" Then はデバッグできましたが、
Me(rs!略 & rs!氏名).ForeColor がエラーになりました。
Meを外したり、rs!略だけにしても同じです。
色を変えたいのは表示させている 時間と略と氏名の一行、一行を略の選択によって色を変えたいです。
日付の登録が済んだら、次は日付別の何かを登録するんじゃないかと予想します。
最終的に、このデータベースを使ってどんな事がやりたいのでしょう。
それ次第で回答が変わるかもしれません。
If Me(rs!略).Value = "関" Then
を
If rs!略.Value = "関" Then
に変更してみてください。
あと、
Me(rs!略 & rs!氏名).ForeColor
もエラーになりそうです。
とのことですが、なんの色を変えたいのかよく考えてみてください。
hatena様
お手数をおかけいたします。
If Me(rs!略).Value = "関" Then
が選択されます。
エラーメッセージが出たときに、[デバッグ]ボタンを押すとどの行が選択表示されますか。
お二方ともご回答ありがとうございます。さすがです。
Aさん、Bさん、CさんともそれぞれログインIDとパスワードを設定していますので、ログインボタンでそれをトリガーにしてリンク先を切り替えるように組んでみます。
本当にありがとうございました。
たびたびになりますが、ご教授ください。
略の条件によって色を変えるように指定したいのですが、
実行時エラー2465
指定した式で参照されている”関”フィールドが見つかりません。
と表示されてしまいます。
VBAは以下になります。できれば、時間、略、氏名を一緒に変えたいのですが
よろしくお願いいたします。
ublic Sub SetSchedule()
Dim i As Integer, rs As DAO.Recordset
For i = 1 To 42
Me("T" & i).Caption = ""
Next
Set rs = CurrentDb.OpenRecordset( _
"SELECT 日付, 時刻, 略, 氏名 FROM T予定 WHERE " &
"日付>#" & FirstDay & "# AND 日付<=#" & FirstDay + 42 & "# ORDER BY
時刻", _
dbOpenForwardOnly, dbReadOnly)
Do Until rs.EOF
With Me("T" & rs!日付 - FirstDay)
.Caption = .Caption & Format(rs!時刻, "hh:nn") & " " & rs!略 &
rs!氏名 & vbCrLf
If Me(rs!略).Value = "関" Then
Me(rs!略 & rs!氏名).ForeColor = 8388608
Else
Me(rs!略 & rs!氏名).ForeColor = 0
End If
End With
rs.MoveNext
Loop
rs.Close: Set rs = Nothing
End Sub
>> 3
流石です。
ググったら類似質問回答がありました。確かにあのバックアップの真似では無理そうですね。
T'sWare Access Tips #179 ~もう1つのAccessデータベースを開く方法(COM版
CommandBars.ExecuteMsoメソッド
idMsoの調べ方
あれやこれやとやったんですけど、accde作成ダイアログにうまくSendkey出来ずに詰みますね。
【EXCEL VBA | ノート】Windowハンドルを取得して、ファイル選択ダイアログボックスを操作する
WindowsAPI関数まで手を広げれば出来るのかもしれないけれど、挫折しました。
>> 3
あぁぁ〜さすがですわ。よく練られていますね。
LostFocusではイベントをキャンセルできませんので、Exitイベントを使ってください。
自動生成されるイベントプロシージャの引数に
Cancel As Integer
がある場合はCancel = True
でイベントのキャンセルが可能です。LostFocusのイベントプロシージャは引数がないのでキャンセルはできません。50個のACCDEファイルを作成するという考え方ではなく、
ACCDEファイルの起動時にリンクテーブルのリンク先を適切に変更する処理を持たせれば、配布するACCDEファイルは一つですみます。
元のAccdbファイルに、リンクテーブルのリンクが切れていたらリンク先を変更するFunctionを作成しておきます。
変更するリンク先は、データベースファイルと同じフォルダーにあるテキストファイルにリンク先パスを格納しておいて、それを参照するようにします。
このFunctionをAutoExecマクロで起動時に実行するようにします。
最初に配布するときだけ、リンク先パスを格納したテキストファイルと一緒に配布して、同じフォルダーに入れておいてもらいます。
次回から、Accdeファイルのみ配布すれば、最初の起動時にリンク先を変更してくれます。
ファイルはリンクテーブルで構成しています。Aさん、Bさん、Cさんはそれぞれ遠く離れた別の場所にいて、別々ののサーバーで閲覧をします。しかしそれぞれが別の拠点から大元のリンクテーブルにアクセスすると動作速度が遅くなるため、それぞれのサーバーにリンクテーブルを定期的にコピーし、それを閲覧専用として利用します。そのためそれぞれの環境に応じてリンク先をVBAで変更しています。
変更したものをそれぞれコンパイルして配布しているんですが、それって結局おっしゃるとおり50個のACCDEファイルができるということになりますね。なのでボタン一つでできないかなあという相談です。
配布のやり方、やった事がないのに回答して申し訳ないですが、1回コンパイルして出来上がったファイルをコピペ配布するようなイメージを持っています。状況は、Aさんに配布する為に、1回コンパイル、続けて、Bさんに配布する為に再度もう1回コンパイル…という事なのでしょうか?それとも、例えば、50個のAccessファイルを手作業で50回コンパイルするのは大変という事でしょうか?
>> 13
>> 14
もう一度状況を整理するのはどうでしょう?具体的に不具合やエラーコードやコードを含めて質問を立て直すといいですよね。確認済みだと思いますが、ファイル名を参照してあれやこれや動作するような仕組みになっていませんよね?
本日、別の顧客でも同様の不具合が発生しました。環境は、Office365のアクセスです。同様にMDBを作成し直して、実行したところ、不具合が発生しました。原因は、ファイル名にアルファベットとアンダーバーを使用していたことでした。アンダーバーをなくし、アルファベットのみに変更したら、何度起動・終了を繰り返してもOKでした。
了解です。クエリの元になっているテーブルは、Thp_サイト登録情報でしょうか。Thp_サイト情報でしょうか。両方でしょうか。もし、片方だけならば、デザインタブ『テーブルの表示』を押して、両方表示、紐付けておくと便利ですよね。
登録キーワードは、Thp_サイト登録情報に保持する、Thp_サイト情報に保持しない。とすればいいのかもしれませんね。
以下、なんちゃってイメージです。
フィールド内の文字数を数える(LEN関数) - Accessの使い方みたいな感じと想像します。
お返事ありがとうございます。りんごさん。
>横から失礼しますね。登録キーワードは、1つのサイトに1つだけ?それとも、複数設定出来るようにするの?登録キーワードを管理するテーブルはあるの?
これは普通に複数設定できるようにしたいなと思っています。改めて考えると全く妥当ではないかもしれません…
空白を設け、羅列しても。ここは妥当ではないかも。
>何かをカウントしたいの?
これは、サイトの登録文の文字数のカウントです。クエリで設定しました。
>それと、念のために確認ですが,クエリじゃなくて、Qhp_サイト登録情報_カウントという名前のテーブルですか?
これはクエリです。クエリの時に、Qという文字列を入れて分かりやすくしております。
アクセスって奥深いですね。
hatenaさんにせっかくお返事いただいているのに、
私の頭では理解しきれず、混乱している状態です。
でも、何とか頑張りたいと思います。
>> 10
横から失礼しますね。登録キーワードは、1つのサイトに1つだけ?それとも、複数設定出来るようにするの?登録キーワードを管理するテーブルはあるの?
何かをカウントしたいの?
それと、念のために確認ですが,クエリじゃなくて、Qhp_サイト登録情報_カウントという名前のテーブルですか?
「Thp_サイト情報」がメインテーブルで、「Qhp_サイト登録情報_カウント」にメインテーブルの「登録サイト名」「登録キーワード」を表示させたいということですよね。
「Qhp_サイト登録情報_カウント」に「サイト情報ID」があるので、それをもとに、メインテーブル「Thp_サイト情報」から、「登録サイト名」「登録キーワード」を参照して表示させることが可能なので、「Qhp_サイト登録情報_カウント」には「登録サイト名」「登録キーワード」は不要です。データベースでは同じデータを複数個所に格納しないというのが原則です。
別テーブルのデータを参照する方法はいろいろありますので、その時に応じて使い分けることになります。
基本は「オートルックアップクエリ」という機能です。詳細は下記を参照ください。
Accessの「オートルックアップクエリ」とは | できるネット
これを作っておいて、フォームやレポートのレコードソースに設定すればVBAなしでメインテーブルのデータを表示させることができます。
あと、フォームなとではコンボボックスのColumnプロパティを使う方法もよく使います。
今回のフォームはコンボボックスがあるので、テキストボックスのコントロールソースに、
=サイトID.Column(1)
=サイトID.Column(2)
と設定すれば「登録サイト名」や「登録キーワード」を表示させることが可能です。
お世話になっております。
以下が情報です。
フォームのレコードソースのテーブル名、
「Qhp_サイト登録情報_カウント」
フィールド構成
「サイト登録情報ID(主キー)
サイト情報ID
登録サイト名
登録キーワード
備考1」
です。
コンボボックスの値集合ソースのテーブル名
「Thp_サイト情報」
フィールド構成
「サイト情報ID(主キー)
登録サイト名
登録キーワード
登録文
備考1」
となっております。
それではどうぞ、
よろしくお願い致します。
連結フォームなら、下記の情報を提示てしもらえますか。
フォームのレコードソースのテーブルのテーブル名、フィールド構成、主キー設定
コンボボックスの値集合ソースのテーブル名、フィールド構成、主キー設定
もっと基本的なことの確認が漏れていたんですが
差し込み印刷用のデータ ソースとしてテーブルやクエリを使用する
(
SELECT TOP1
のような)静的なクエリが組めるのであればそのままデータソースにできるのでは?ついでにサンプルを組んでいたらいろいろハマったのでその辺の情報を追記しておきます
Word文書に差し込みの設定をしておくと、ファイルを開く時に確認ダイアログ(「この文書を開くと、次の SQL コマンドが実行されます。」)が表示されます
回避方法としてレジストリを修正する方法がありますが、影響範囲が大きく望ましくありません。書式の設定だけしたWordファイルを用意して、データソースは動的に読み込むとよさそうです
MailMerge.OpenDataSource メソッド (Word)
一度差し込み設定をしたWord文書を作成したら、差し込み印刷の開始→標準の Word 文書でデータのリンクを解除して保存しなおします(開いてもダイアログの出ない文書にする)
都度ACCESS VBAからWord文書を開く→データソースのリンクをします
上記リンク先では
とありますが、hirotonの環境(office 2013)ではうまくいきませんでした。サンプルのコードではファイル指定が
.mdb
なので、古い形式でないとダメなのかもしれませんまた、
Provider=Microsoft.ACE.OLEDB.12.0;
この指定部分はACCESSのバージョンによって変わる可能性がありますプルダウン、行を選択、それぞれの列の値をそれぞれのフィールドに登録したい、という事だったのかしら。上手く汲み取れませんでしたね。
普通にすると、主キーの値をテーブルに入力することになりますよね。事前にプルダウンの元になるテーブルを用意し、AかBか適切なフィールドに主キーを設定して、登録先のフィールドに紐付けておきましょう。
プルダウンのテーブルと登録先のテーブルを主キーで紐付けしておけば、Aの値は「あ」にBの値は「い」なんて必要ないですよね。クエリで参照・表示するだけです。
以上、単独主キーの話でした。複合主キーの場合、どうするかなぁ。
ご回答ありがとうございます。
1→2→3の順で実行するという認識でおります。
作業テーブル(中間テーブル)を用意するという方法は思いつきませんでした。プログラム実行の都度上書きするということで対応しました。1レコードだけを対象にするのはSELECT TOP1でいけました。
https://oshiete.goo.ne.jp/qa/7681553.html
あたりを参考に差し込み部分のVBAを書こうと考えております。
ありがとうございました。
お返事をありがとうございます。
連結フォームみたいで、
コントロールソースにも、
値集合ソース、値集合タイプにも
データーがありました。
フォームの「レコードソース」プロパティの設定はどうなってますか。
空欄ですか、それとも、テーブル名かクエリ名あるはSQLが設定されてますか。
空欄なら、非連結フォームになります。
なにか設定されていれば、連結フォームになります。
まずは、これについて回答してください。
非連結フォームなら、hirotonさんの回答でいいでしょう。ただし、テキストボックスに代入した値は、どこにも保存されないので、それをどのようにするかは、自分で処理を構築する必要があります。
連結フォームならテーブル設計に問題がある可能性が大きいです。
あえて「正規化崩し」で冗長なデータを持たせるという設計もありますが、質問内容からそのレベルでないように感じます。
そんな気がしてたので大丈夫ですよ
「普通」が難しい表現ですが、
・コンボボックスの値はそのコントロールソースのフィールドに入力されます
・入力される値は、連結列で指定した列です
質問の内容は一般には上の意味でとられると思います。(やろうとしてることがわからない。テーブル構造おかしくない?という話になる)
コンボボックスの更新後処理イベントで追加の入力処理をしてあげればいいです
の場合、
新たにテキストボックスを設置し
とする
Column(1)
の数字は列番号(左端が0)です沢山のお返事ありがとうございます。
あんまりAccessに詳しいほどでもないので、
ご返信を見ながらも頭がこんがらがってます。
すみません。以下的を射てご返信出来て
いなかったらすみません。
フォームでの表示は、
サイトID、サイト名でプルダウンを作り
「1|嬉しいあいうえお」ですね。
そうして、
「1」をサイトIDに
「嬉しいあいうえお」をサイト名に
プルダウンの1アクションで入力したいと思っております。
可能でしょうか?