遅まきながら参加させてください(汗)。
hiroton さんがレスされていたように、時代は「クラウド」で「ノーコード」で「RPA」だ・・・とは思います。 自分は前任担当者が作りこんだRPAを使っている立場(エラーが出たら、そこだけ人力で解決する)ですが、 周りでVBA信者?みたいな人がいるので、困っています。
先日もインターネット上にアップロードするファイルのファイルサイズをチェック(1ファイルあたりの 上限が決まっている)するのに、「VBAで組んだらチェックできるし」と言われて目がテンになりました。
いやいや、そもそも「ファイル準備するときに担当者がファイルサイズ目視して確認すれば良くね?」って 思うんですよね。 RPAの処理のなかにアレコレ組み込みすぎると、その人がいなくなった時にメンテできなくなりますし、 困るじゃないですか。 (もともとRPAで参照しているDBがAccess DBなので、個人的にはRPAでも複雑な分岐処理を入れるのは 良くないと考えています。)
RPAだって万能ではないのに、VBA無敵?みたいな感じで「24時間、ノーチェック(要は無人でOK)で 処理できるから」と言い出して、他の担当者と「いや、それ無理ですよ」って伝えたのですが、 聞く耳持たず。。。
そもそもネットワーク遅延などの外的要因も関係するのに、「VBAサイコー!」とか「RPAは何でもOK!」 みたいな考えは(ご本人は自分のプログラミングスキルなどに自信があるのかもしれませんが) キケンだと言いたいです。
こっちは運用のこととか、業務のことなどを広い視野で見て&考えて意見を伝えているのですが、 「自分が正しい」とか逆ギレしそうなので(昨年、外に出すモノの品質に問題があったので 問題点を伝えたところ、「自分が確認しているんだから問題ない!」と強い口調で言い返されたので、 それ以降は「知らぬ存ぜぬ」で当人に伝えることを諦めました)、 マジで困っています(泣)。
あ、愚痴みたいになってしまってスミマセン。。。
hatenaさん 先程ご提示していただいた文で、問題解決出来ました!! ありがとうございます!
ハイパーリンクを設定した非連結テキストボックスで、入力すると表示テキストのみになるのだと思われます。 つまりハイパーリンクアドレスは無し""という状態
ハイパーリンクの構造を理解していない上に、非連結を使って入力をした事で混乱を招いてしまったのですね...。 申し訳ございませんでした。
他にも型チェック、参照整合性チェックなど、考慮しなければならないことか多数あります。 複数ユーザーで共有する場合、排他処理なども必要になってきます。 これらのことをすべて実装するとなるとなまはんかのスキルでは無理です。 これらを実装できたとして、連結にくらべてどれほどのメリットがあるのかはなはだ疑問なので、 私自身は非連結はほとんど使いません。 複数ユーザーで共有する場合は、安定性を高めるために非連結にすべきという意見も散見しますが、 上記の点についての言及はほとんど見ません。
VBA関連の書籍のキャッチフレーズに「現場で即使える」と謳われるものが沢山ありますが 現場から要求されるリクエストは、書籍に載っていないものが圧倒的多いように感じますので hatenaさんの仰る通り、全ての要求に応えられるにはハイレベルのスキルが求められますね。
今回はハイパーリンクについて、hatenaさん・skさんに沢山学ばせていただきました。 長々とお付き合いいただき、改めてお礼申し上げます!ありがとうございます!
まだまだ聞きたいことは沢山あるのですが、それはまた改めて聞きたいと思います。 ありがとうございました!!これからもよろしくお願いいたします!
非連結フォームの設計は、連結フォームならAccessが自動でいろいろしてくれていることをすべて自前で処理する必要がでてきます。 非連結で設計するということは、このAccessが裏でやっていてくれてることを理解、把握しておく必要があります。
ハイパーリンクは格納されているデータと表示されているテキストが一致していないというのが、難しくなる原因です。 他にも日付/時刻型もそうです。
他にも型チェック、参照整合性チェックなど、考慮しなければならないことか多数あります。 複数ユーザーで共有する場合、排他処理なども必要になってきます。
これらのことをすべて実装するとなるとなまはんかのスキルでは無理です。 これらを実装できたとして、連結にくらべてどれほどのメリットがあるのかはなはだ疑問なので、 私自身は非連結はほとんど使いません。
複数ユーザーで共有する場合は、安定性を高めるために非連結にすべきという意見も散見しますが、 上記の点についての言及はほとんど見ません。
複数ユーザーで共有することで不安定になるような規模のシステムなら、すでにAccessではなく他のRDBを検討すべきだと思います。 あくまで私見ですので参考程度に。
コンパイルエラーは解消されましたが、今度は直前にテキストボックスに入力したPC内のファイルパスが 更新ボタンをクリックしたと同時に消えてしまいます。
以下に関しては私の推測です。試してみたわけではありまん。
まず、skさんの回答にもありましたがハイパーリンクの内部的な書式は下記になります。
表示テキスト#ハイパーリンクアドレス#サブアドレス#ヒントテキスト
対応策としては、ハイパーリンクアドレスがあればその前後に"#"を付ける。 なければ、表示テキストの前後に"#"を付ける。
Dim sAddress As String sAddress = HyperlinkPart(Me("txt_詳細リンク" & R).Value, acAddress) If sAddress <> "" Then sAddress = "#" & sAddress & "#" Else sAddress = HyperlinkPart(Me("txt_詳細リンク" & R).Value, acDisplayText) If sAddress <> "" Then sAddress = "#" & sAddress & "#" End If
このように状況、原因を調べて、対策を考えるという手順を踏みます。 あくまで、推測なのでこれでうまくいくとは限りません。
hatenaさん、長々とお付き合い頂いてありがとうございます。 skさんもありがとうございます!とても感謝しております!! デバック方法については書籍を参考に試してみます。 特に急ぐようなことでは無いので、時間をかけて学習してみます。 ありがとうございました。
テーブル名 には実際にはどのような名前がはいってますか。 テーブル名に使用すべきでない文字が含まれているとそのようエラーになります。 そのような場合、名前の前後に"[" "]"を付けると回避できます。
下記のように変更したらどうでしょう。
rsM.Open "[" & テーブル名 & "]" , cn , adOpenStatic, adLockOptimistic
可能ならばこのような特殊文字は使わないテーブル名に変更することをお勧めします。
Access データベースで特殊文字を使用したエラー - Microsoft 365 Apps | Microsoft Learn
skさんの#12の回答のSQLでどのような状態で格納されているか確認して、表示されない原因と対策を考えましょう。
私が思うに非連結でいくなら、テキストボックスの「ハイパーリンクあり」は「いいえ」に設定しておいた方がいいように思います。
実際にサンプルを作成して動作確認しているわけではないので、推測で提案しています。
非連結フォームの設計はかなりのスキルが要求されます。 連結でできていたものを、勉強のために非連結に変更しているということなので、 このような不具合を自分で解決できるようなスキルアップが必要ということです。 そのためにはまずはデバッグ方法を学習しましょう。 これを使って原因の追究、解決を繰り返すことによってスキルがアップします。 「VBA デバッグ」をキーワードにググれはいろいろ解説ページが見つかるので、 そこでデバッグの方法の理解を深めることをお勧めします。
hatenaさん コンパイルエラーは解消されましたが、今度は直前にテキストボックスに入力したPC内のファイルパスが 更新ボタンをクリックしたと同時に消えてしまいます。私の書き方に問題ありますか?
Private Sub btn_更新_Click() Dim sqlList As Collection Set sqlList = New Collection 'コレクションを作成 〜省略〜 Dim R As Long For R = 1 To 10 If Nz(Me("txt_特記ID" & R).Value, "") <> "" Then '「txt_特記ID」が空でなければ Dim sAddress As String sAddress = HyperlinkPart(Me("txt_詳細リンク" & R).Value, acAddress) If sAddress <> "" Then sAddress = "#" & sAddress & "#" '実行 strSQL = _ "UPDATE T_特記事項 " & _ "SET " & _ "口座番号 = '" & Me.txt_口座番号.Value & "', " & _ "特記事項 = '" & Me("txt_特記事項" & R).Value & "', " & _ "特記事項詳細 = '" & sAddress & "' " & _ "WHERE ID = " & Me("txt_特記ID" & R).Value & ";" sqlList.Add strSQL ElseIf Not IsNull(Me("txt_特記事項" & R).Value) Then '「txt_特記事項」が空でなければ strSQL = _ "INSERT INTO T_特記事項 (口座番号, 特記事項, 特記事項詳細) " & _ "VALUES" & _ "('" & Me.txt_口座番号.Value & "', " & _ "'" & Me("txt_特記事項" & R).Value & "', " & _ "'" & Me("txt_詳細リンク" & R).Value & "');" sqlList.Add strSQL End If Next R '「T_クレーム履歴」のデータを更新する Dim Z As Long For Z = 1 To 10 If Nz(Me("txt_クレームID" & Z).Value, "") <> "" Then '「txt_クレームID」が空でなければ sAddress = HyperlinkPart(Me("txt_クレーム詳細リンク" & Z).Value, acAddress) If sAddress <> "" Then sAddress = "#" & sAddress & "#" '実行 strSQL = _ "UPDATE T_クレーム履歴 " & _ "SET " & _ "口座番号 = '" & Me.txt_口座番号.Value & "', " & _ "発生年月 = '" & Me("txt_発生年月" & Z).Value & "', " & _ "クレーム内容 = '" & Me("txt_クレーム内容" & Z).Value & "', " & _ "是正処置 = '" & Me("txt_是正処置" & Z).Value & "', " & _ "クレーム詳細 = '" & sAddress & "' " & _ "WHERE ID = " & Me("txt_クレームID" & Z).Value & ";" sqlList.Add strSQL ElseIf Not IsNull(Me("txt_クレーム内容" & Z).Value) Then '「txt_クレーム内容」が空でなければ strSQL = _ "INSERT INTO T_クレーム履歴 (口座番号, 発生年月, クレーム内容, 是正処置, クレーム詳細) " & _ "VALUES" & _ "('" & Me.txt_口座番号.Value & "', " & _ "#" & Me("txt_発生年月" & Z).Value & "#, " & _ "'" & Me("txt_クレーム内容" & Z).Value & "', " & _ "'" & Me("txt_是正処置" & Z).Value & "', " & _ "'" & Me("txt_クレーム詳細リンク" & Z).Value & "');" sqlList.Add strSQL End If Next Z
If sAddress <> "" Then sAddress = "#" & sAddress & "#"
何度もスミマセン。 今度は下記で「コンパイルエラー 変数が定義されていません」となりました。 If sAddress <> "" Then s = "#" & sAddress & "#"
「コンパイルエラー 変数が定義されていません」となり If sAddress <> "" Then s = "#" & Address & "#" となりました。
あっ、すみません。タイプミスです。下記に修正してください。 If sAddress <> "" Then s = "#" & sAddress & "#"
If sAddress <> "" Then s = "#" & sAddress & "#"
HyperlinkPartという関数、初め見たかもしれません。
私の 6 の回答でリンクを置いてます。
hatenaさん 提示していただいた文に差し替えてみたところ 「コンパイルエラー 変数が定義されていません」となり If sAddress <> "" Then s = "#" & Address & "#" となりました。
HyperlinkPartという関数、初め見たかもしれません。 勉強になります!
今回の場合はどちらでもいいでしょう。
例えば、特定の条件の場合はフォーカスさせずに別のコントロールにフォーカスさせたいというような場合は、取得時でないとだめですね。ただ、このような設計はたいてい悪手ですね。
特定の条件を満たすまで使用不可にしておくとか、、、ほかの方法を検討した方かいいです。
こんな感じでどうでしょうか。
If Nz(Me("txt_特記ID" & R).Value, "") <> "" Then '「txt_特記ID」が空でなければ Dim sAddress As String sAddress = HyperlinkPart(Me("txt_詳細リンク" & R).Value, acAddress) If sAddress <> "" Then s = "#" & Address & "#" strSQL = _ "UPDATE T_特記事項 " & _ "SET " & _ "口座番号 = '" & Me.txt_口座番号.Value & "', " & _ "特記事項 = '" & Me("txt_特記事項" & R).Value & "', " & _ "特記事項詳細 = '" & sAddress & "' " & _ "WHERE ID = " & Me("txt_特記ID" & R).Value & ";" sqlList.Add strSQL
下記の文ですと、パスの前後に"が付いた状態で書き込まれていました。
"特記事項詳細 = '" & Me("txt_詳細リンク" & R).Value & "'"
そして、修正文ありがとうございます。 早速試してみました。
"特記事項詳細 = '#" & HyperlinkPart(Me("txt_詳細リンク" & R).Value, acAddress) & "#' " 上記の文に修正をして、更新してみたところ アドレス(パス)を書き込むことが出来ました。 が、ブランクのレコードには「##」と書かれていました。
遅くなりました。 まずは「T_特記事項」「T_クレーム履歴」に関するSELECT文です。
strSQL = _ "SELECT ID, 特記事項, 特記事項詳細 " & _ "FROM T_特記事項 " & _ "WHERE 口座番号 = '" & Me.txt_口座番号.Value & "';" Set daoRs = daoDb.OpenRecordset(strSQL) Dim R As Long: R = 1 Do Until daoRs.EOF = True If R > 10 Then MsgBox "表示できないレコードが存在しています", vbExclamation, "エラー" Exit Do End If Me("txt_特記ID" & R).Value = daoRs!ID Me("txt_特記事項" & R).Value = daoRs!特記事項 Me("txt_詳細リンク" & R).Value = daoRs!特記事項詳細 daoRs.MoveNext R = R + 1 Loop daoRs.Close strSQL = _ "SELECT ID, 発生年月, クレーム内容, 是正処置, クレーム詳細 " & _ "FROM T_クレーム履歴 " & _ "WHERE 口座番号 = '" & Me.txt_口座番号.Value & "';" Set daoRs = daoDb.OpenRecordset(strSQL) Dim Z As Long: Z = 1 Do Until daoRs.EOF = True If Z > 10 Then MsgBox "表示できないレコードが存在しています", vbExclamation, "エラー" Exit Do End If Me("txt_クレームID" & Z).Value = daoRs!ID Me("txt_発生年月" & Z).Value = daoRs!発生年月 Me("txt_クレーム内容" & Z).Value = daoRs!クレーム内容 Me("txt_是正処置" & Z).Value = daoRs!是正処置 Me("txt_クレーム詳細リンク" & Z).Value = daoRs!クレーム詳細 daoRs.MoveNext Z = Z + 1 Loop daoRs.Close
色々ありがとうございます。大変参考になりました。シンプルにサブフォームのコンボボックスに”Me!コンボ.Requery”でしまして上手くいきました。 参考にまで教えて欲しいのですが、この場合のフォーカスイベントは取得時の方がいいのでしょうか?取得後でも同じでしょうか? これの使い分けがよく分かってないもので。
現時点ではレコード数も20件と少ないので、skさんからご提示して頂いたSQL文は使わず、 一個一個#を削除して、「#[特記詳細事項]#」のようなあるべき姿にしたところです。
そのように修正済みで、[特記詳細事項]の部分がURLということで、テキストボックスが「ハイパーリンクあり」かつ「ハイパーリンクである場合」の設定なら、
"特記事項詳細 = '#" & Replace(Me("txt_詳細リンク" & R).Value, """", "") & "#' "
の部分を
でよさそうです。 あるいは、HyperlinkPart関数でアドレス部分のみ取り出して、
"特記事項詳細 = '#" & HyperlinkPart(Me("txt_詳細リンク" & R).Value, acAddress) & "#' "
見当違いのコードを送ってしまい、 申し訳ありません。 該当コードは後ほどお送りします。
冒頭3でも書き込みましたが、 連結フォームで作って運用中のものを、 VBAの勉強を目的として取り組んでいる次第です。 その為、非連結となっております。
提示いただいたコードは、「T_機械設定」テーブルのデータを読み込んでいます。 質問のコードは、「T_特記事項」「T_クレーム履歴」への書き込みです。 「T_特記事項」「T_クレーム履歴」からの読み込みの部分のコードを提示してもらえますか。
あと、連結フォームでなく非連結フォームで読み込み、書き込みしている理由はなんでしょうか。
hatenaさん、ありがとうございます!
この「レコードを読み込ませる」とは具体的にどのように読み込ませているのでしょうか。 「非連結」なので、何かしないと何も表示されません。
「btn_読込」に、下記のようなクリック時のイベント(一部抜粋)を設けて、格納させています。
Private Sub btn_読込_Click() Call loadForm '読込を呼び出し End Sub Private Sub loadForm() If IsNull(Me.txt_口座番号.Value) Then Exit Sub '「txt_口座番号」が空なら中止 Call initializeForm On Error GoTo ErrorHandler Dim daoDb As DAO.Database Set daoDb = CurrentDb '接続 Dim daoRs As DAO.Recordset Dim strSQL As String strSQL = _ "SELECT 品名, 厚さ, 幅, 長さ, 巻取側の張力, 巻取側のテーパー, 巻戻側の張力, 巻戻側のテーパー, " & _ " 巻取方向, 巻戻方向, ニップの使用可否, ニップ圧, 巻取速度, サンプル採取, 巻取側の巻芯種別, " & _ " 巻取側の巻芯内径, 巻取側の巻芯厚さ, 巻取側の巻芯幅, タッチロールの材質, タッチロールの寸法, EPC検出位置切替 " & _ "FROM T_機械設定 " & _ "WHERE 口座番号 = '" & Me.txt_口座番号.Value & "';" Set daoRs = daoDb.OpenRecordset(strSQL) If daoRs.BOF = True And daoRs.EOF = True Then '該当レコードが無かったら MsgBox "対象レコードがありません。", vbInformation, "確認" 'メッセージを出力 GoTo Finally '接続解除へジャンプ(親レコードが無ければ子レコードが読込できないため) End If Me.txt_品名.Value = daoRs!品名 Me.txt_厚さ.Value = daoRs!厚さ Me.txt_幅.Value = daoRs!幅 Me.txt_長さ.Value = daoRs!長さ Me.txt_巻取張力.Value = daoRs!巻取側の張力 Me.txt_巻取テーパー.Value = daoRs!巻取側のテーパー Me.txt_巻戻張力.Value = daoRs!巻戻側の張力 Me.txt_巻戻テーパー.Value = daoRs!巻戻側のテーパー Me.cmb_巻取方向.Value = daoRs!巻取方向 Me.cmb_巻戻方向.Value = daoRs!巻戻方向 Me.cmb_ニップ可否.Value = daoRs!ニップの使用可否 Me.txt_ニップ圧.Value = daoRs!ニップ圧 Me.txt_巻取速度.Value = daoRs!巻取速度 Me.cmb_試験サンプル.Value = daoRs!サンプル採取 Me.cmb_種別.Value = daoRs!巻取側の巻芯種別 Me.txt_巻芯内径.Value = daoRs!巻取側の巻芯内径 Me.txt_巻芯厚さ.Value = daoRs!巻取側の巻芯厚さ Me.txt_巻芯幅.Value = daoRs!巻取側の巻芯幅 Me.cmb_タッチロール材質.Value = daoRs!タッチロールの材質 Me.txt_タッチロール寸法.Value = daoRs!タッチロールの寸法 Me.cmb_検出位置.Value = daoRs!EPC検出位置切替 daoRs.Close
「######・・・」というのは、例えば「######https://zawazawa.jp/ms-access/######」というような表示でしょうか。(URL部分は一例)
その通りです。 既存レコードには、更新回数分であろう#が前後に増えていて、 レコードの無いところには、同じく更新回数分であろう#で埋め尽くされていました。
悩ましいですねぇ
>> 2のhatenaさん提示の方法でいいと思いますが、個人的にはあまりSetFocusを使いたくないので別解も載せておきます
SetFocus
ACCESS VBA 別フォームのイベントを呼び出す方法(VBAコード公開)(たすけてACCESSさん)
(デフォルトで生成されるあれこれを弄るといろいろと混乱するので、publicなそれ用のプロシージャを作るというのが、「hirotonならこうする」ですかね)
public
要はこのRequeryをさせたい
の観点からなら
Froms!フォームAメイン.Form!サブフォーム.Form!コンボ.Requery
という方法もあります。が、プログラミング的な観点から同じ処理を別々な場所に記述するのは良くないので、今回の形なら「[tx文字]の更新後イベント」を発生させる方向が良いのでは、と思います
その他の方法として、「コンボボックスのリストが表示されるのはコンボボックスを使うとき」なので、コンボボックスのフォーカス取得時イベントでMe!コンボ.Requeryを行うなんて手法もあります
Me!コンボ.Requery
ありがとうございました。その方法で出来ました。 こんな事が出来るとは知りませんでした、便利です。 お世話になりました。
色々と説明不足してました(すみません)。フォームAのサブフォームにあるコンボボックスの値集合ソースに Like "" & [Forms]![フォームAメイン]![tx文字] & "" としており絞り込みさせています。 フォームBが開かない場合には[tx文字]の更新後イベントに [サブフォーム].Form![コンボ].Requeryとしています。 要はこのRequeryをさせたいのです(フォームBからVBコードでフォームAメインの[tx文字]に代入)。
フォーカスセットをしておくと更新するとネット情報で見たので下記にコード記述しております
正確には、フォーカスをセットしておいて、Textプロパティに代入すると、更新イベントが発生します。
[Forms]![フォームAMain]![txボックス].SetFocus [Forms]![フォームAMain]![txボックス].Text = "所定文字列" DoCmd.Close acForm, "フォームB"
下記もご参考に。
値の代入で更新イベントを発生させる - hatena chips
ただし、hirotonさんも指摘されているように、コンボボックスのリストの絞り込みをどのようにしているかによります。 サブフォームが帳票フォームだったりするとさらに複雑な要因がでてきます。
上記の方法でうまくいけばいいですが、そうではない場合は、 絞り込みをどのようにしているのかと、コンボボックスは連結なのか、非連結なのか、サブフォームが帳票フォームなのか、、、などの情報が必要になります。
当方でサンプルを作成して確認してみましたが、症状は再現できませんでした。 パーションか環境に依存する症状だとするとこちらから原因を究明するのは難しいですね。
回避策としては、 条件付き書式を使わずに、VBAで背景色を変更するようにしてはどうでしょう。
コード例 詳細セクションのフォーマット時のイベントプロシージャに下記のように記述します。
Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer) If Me.区分.Value = "回収" Then Me.テキストボックス名.BackColor = vbYellow Else Me.テキストボックス名.BackColor = vbWhite End If End Sub
上記は"回収"の場合、背景が黄色になります。
他の色を設定したい場合は、下記などを参考に。
Accessでコントロールの色を変える2つの方法|アズビーパートナーズ
そもそも
コンボボックス絞り込みをメインの非連結テキストボックスに含まれている文字列をLikeで抽出させています。
を、具体的にどのように行っていますか?
コンボボックスはそのコントロールソースに従って表示内容が決定されますが、もう少し具体的には、コントロールソースの内容を読み込むタイミングで決定されます。
そのタイミングの一つは、もちろん、「フォームを開いたとき」です。このタイミングでは特に気にすることなく自動で行われます。逆に言えば、通常これで十分なので、その他のタイミングで更新したい場合は「コントロールソースの読み込み直し処理」を自前で組まなければなりません
なので、上記指摘が「できている」のであれば「同じようにやればいい」です
フォーカスセットをしておくと更新するとネット情報で見た
こんな仕様はhirotonは知らないですね (今回組んだシステムは)フォーカスセットをしておくと更新する(ように作ったのでフォーカスをセットすればいい)とかなら作れるかもしれません。(よくあると思います) ならば、重要なのは、フォーカスをセットする方法ではなく、その時にどのような処理が行われるか?の方です。そこに「コントロールソースの読み込み直し処理」があると思います
プロパティを比べても相違はありませんでした。その後色々して分かった事があります。レポートに条件付き書式を設定すると、この現象になります。[区分]="回収"の時に塗りつぶし設定にしてます。レポート上のどのフィールドにその設定にすると#name?となります(ウィザードで作成した分も)。問題のあったレポートも条件付き書式を削除すると重複データ非表示になります。⇒条件付き書式と重複データ非表示を一緒に設定することは無理なのでしょうか?
取り急ぎ、テキストボックスは「非連結」であり「ハイパーリンクあり」かつ「ハイパーリンクである場合」です。
了解です。回答に必須にな情報でした。
試しに、このテキストボックスを「ハイパーリンクなし」に変換して、消えたレコードを読み込ませると 消えたレコードは「######・・・」と表示されました。
『消えたレコードは「######・・・」と表示されました』ということは、UPDATE で前後に"#"を付加することを繰り返した結果でしょう(すでにskさんの回答で指摘されてます)。 誤った状態で保存されているのでまずはそれを修正する必要がありますね。
とりあえずskさんの回答の12のSQLのクエリを作成して、それを開いてテーブルにどのような状態で格納されているか確認する必要があります。
すべたのレコードが「######https://zawazawa.jp/ms-access/######」というような状態(#の数はまちまちだがURLの前後に#)でしょうか。 それ以外の書式のものもありますか。あるなら、それを例示してください。
遅くなりました。 私の説明不足によりお二方には色々と推測させてしまい誠に申し訳ないです!
取り急ぎ、テキストボックスは「非連結」であり「ハイパーリンクあり」かつ「ハイパーリンクである場合」です。 試しに、このテキストボックスを「ハイパーリンクなし」に変換して、消えたレコードを読み込ませると 消えたレコードは「######・・・」と表示されました。 この該当テーブルのハイパーリンク型のフィールドを覗くと、「######・・・」であろうレコードはブランクでした。
hatenaさんが提示された通りコードを修正してみましたが、結果は「######・・・」となりました。
よろしくお願いします!
コードをどのように修正するかはともかくとして、テーブル[T_特記事項]のフィールド[特記事項詳細]、およびテーブル[T_クレーム履歴]のフィールド[クレーム詳細]の値が、現時点においてどのように格納されているのかについても、併せて確認された方がよいでしょう。
既に誤った形式のハイパーリンクが格納されてしまっているでしょうから、それらを修正する必要があります。
SELECT [T_特記事項].[ID], [T_特記事項].[特記事項詳細], PlainText([T_特記事項].[特記事項詳細]) AS [特記事項詳細の内部処理上の値] FROM [T_特記事項] ORDER BY [T_特記事項].[ID];
SELECT [T_クレーム履歴].[ID], [T_クレーム履歴].[クレーム詳細], PlainText([T_クレーム履歴].[クレーム詳細]) AS [クレーム詳細の内部処理上の値] FROM [T_クレーム履歴] ORDER BY [T_クレーム履歴].[ID];
INSERT INTO の方は見落としてました。
どちらにしても、連結なのか、非連結なのか、 非連結ならハイパーリンクの設定がどうなっているのか、 まずはそれを明確にしてもらうのが先決ですね。
1から10の連番の付加された10個のテキストボックスである、 SQLでは追加するテーブル側のフィールドは一つである、 ということからこのテキストボックスは非連結コントロールだろうと推測してます。
連結テキストボックスであれ非連結テキストボックスであれ、(ハイパーリンクの構文規則を無視して)無条件で「"#"で区切られた文字列」を更に"#"で囲んだ結果に更新する処理を繰り返し実行すれば、同様の結果がもたらされることは明白です。
もし非連結テキストボックスであるならば、恐らくそれらのテキストボックスの[ハイパーリンクあり]プロパティを「はい」、[ハイパーリンクとして表示]プロパティを「ハイパーリンクである場合」か「常にハイパーリンクにする」に設定されているだと思われますが、そのテキストボックスに"###https://zawazawa.jp/ms-access/###"のような文字列を代入すれば、画面表示上は「何も表示されていない」状態となるでしょう。
###https://zawazawa.jp/ms-access/###
質問文より
サブフォームにある"T_特記事項"と"T_クレーム履歴"には、それぞれ10個のテキストボックスがあって、 そこにPC上の関連ファイルのパスを入力して、ハイパーリンク型フィールド"特記事項詳細"と"クレーム詳細"に UPDATEをしたいのですが、
このテキストボックスがハイパーリンク型フィールドとの連結コントロールだとしたらskさんの通りですね。
私としては、 1から10の連番の付加された10個のテキストボックスである、 SQLでは追加するテーブル側のフィールドは一つである、 ということからこのテキストボックスは非連結コントロールだろうと推測してます。
「サブフォームにある"T_特記事項"と"T_クレーム履歴"には」という表現が連結フォームを連想させるのが紛らわしいですが。
また、[txt_詳細リンク]および[txt_クレーム詳細リンク]が連結テキストボックスではなく非連結テキストボックスであるならば、INSERT INTO ... VALUES ... 文の実行結果も適切ではない可能性があります。
"#"で区切られていない文字列をそのまま代入しているなら、ハイパーリンクの構文上においては「表示テキストのみが設定されている(ハイパーリンクアドレスが2番目ではなく1番目のセクションに入っている)」状態になっているはず。
#name? となるのは、重複データ非表示にしたテキストボックスですか。
ウィザードで作成した簡易なレポートの正常に表示されるテキストボックスと #name? となるテキストボックスのプロパティの設定で異なる部分はないですか。 異なる部分があったら、それを正常な方に合わせたらどうなりますか。
ハイパーリンク型の実体とは、「ハイパーリンク属性を付与されたメモ型(長いテキスト)」である。
ハイパーリンク型の内部処理上の値は、"#" をセクション区切り記号(囲み記号ではない)とした最大4つのセクションで構成された文字列である。
仮に[txt_詳細リンク]および[txt_クレーム詳細リンク]が共にハイパーリンク型のフィールドをコントロールソースとする連結テキストボックスであるとした場合、そのフィールドの値を"#"で囲む(厳密には「先頭に"#"を挿入する」)という操作は、ハイパーリンクの各セクションを1つ右のセクションにずらすことと同義である。
したがって、件の UPDATE 文が繰り返し実行されれば、やがてハイパーリンクの表示テキスト、ハイパーリンクアドレス、サブアドレスが全て空の状態となり、表示上は「パスが消えてしまう」かのように見えてしまうことになる。
その後ウィザードで作成した分のページヘッダーのラベルと詳細セクション部を削除して問題あるレポートからそれらをコピーしました⇒やはり重複データ非表示にすると#name?となります(いいえにすると全て表示) ますます不思議です。
ハイパーリンク型フィールドのURLは"#"で囲むのが仕様だと思います。
Access Tips #526 ハイパーリンク型フィールドにSQLでデータを保存するには? | T'sWare Application.HyperlinkPart メソッド (Access) | Microsoft Learn
Accessのテーブルやクエリのデータを貼り付ける場合は下記で、Markdown書式のテーブルに変換して貼り付けてください。
Markdown Tables generator
遅まきながら参加させてください(汗)。
hiroton さんがレスされていたように、時代は「クラウド」で「ノーコード」で「RPA」だ・・・とは思います。
自分は前任担当者が作りこんだRPAを使っている立場(エラーが出たら、そこだけ人力で解決する)ですが、
周りでVBA信者?みたいな人がいるので、困っています。
先日もインターネット上にアップロードするファイルのファイルサイズをチェック(1ファイルあたりの
上限が決まっている)するのに、「VBAで組んだらチェックできるし」と言われて目がテンになりました。
いやいや、そもそも「ファイル準備するときに担当者がファイルサイズ目視して確認すれば良くね?」って
思うんですよね。
RPAの処理のなかにアレコレ組み込みすぎると、その人がいなくなった時にメンテできなくなりますし、
困るじゃないですか。
(もともとRPAで参照しているDBがAccess DBなので、個人的にはRPAでも複雑な分岐処理を入れるのは
良くないと考えています。)
RPAだって万能ではないのに、VBA無敵?みたいな感じで「24時間、ノーチェック(要は無人でOK)で
処理できるから」と言い出して、他の担当者と「いや、それ無理ですよ」って伝えたのですが、
聞く耳持たず。。。
そもそもネットワーク遅延などの外的要因も関係するのに、「VBAサイコー!」とか「RPAは何でもOK!」
みたいな考えは(ご本人は自分のプログラミングスキルなどに自信があるのかもしれませんが)
キケンだと言いたいです。
こっちは運用のこととか、業務のことなどを広い視野で見て&考えて意見を伝えているのですが、
「自分が正しい」とか逆ギレしそうなので(昨年、外に出すモノの品質に問題があったので
問題点を伝えたところ、「自分が確認しているんだから問題ない!」と強い口調で言い返されたので、
それ以降は「知らぬ存ぜぬ」で当人に伝えることを諦めました)、
マジで困っています(泣)。
あ、愚痴みたいになってしまってスミマセン。。。
hatenaさん
先程ご提示していただいた文で、問題解決出来ました!!
ありがとうございます!
ハイパーリンクの構造を理解していない上に、非連結を使って入力をした事で混乱を招いてしまったのですね...。
申し訳ございませんでした。
VBA関連の書籍のキャッチフレーズに「現場で即使える」と謳われるものが沢山ありますが
現場から要求されるリクエストは、書籍に載っていないものが圧倒的多いように感じますので
hatenaさんの仰る通り、全ての要求に応えられるにはハイレベルのスキルが求められますね。
今回はハイパーリンクについて、hatenaさん・skさんに沢山学ばせていただきました。
長々とお付き合いいただき、改めてお礼申し上げます!ありがとうございます!
まだまだ聞きたいことは沢山あるのですが、それはまた改めて聞きたいと思います。
ありがとうございました!!これからもよろしくお願いいたします!
非連結フォームの設計は、連結フォームならAccessが自動でいろいろしてくれていることをすべて自前で処理する必要がでてきます。
非連結で設計するということは、このAccessが裏でやっていてくれてることを理解、把握しておく必要があります。
ハイパーリンクは格納されているデータと表示されているテキストが一致していないというのが、難しくなる原因です。
他にも日付/時刻型もそうです。
他にも型チェック、参照整合性チェックなど、考慮しなければならないことか多数あります。
複数ユーザーで共有する場合、排他処理なども必要になってきます。
これらのことをすべて実装するとなるとなまはんかのスキルでは無理です。
これらを実装できたとして、連結にくらべてどれほどのメリットがあるのかはなはだ疑問なので、
私自身は非連結はほとんど使いません。
複数ユーザーで共有する場合は、安定性を高めるために非連結にすべきという意見も散見しますが、
上記の点についての言及はほとんど見ません。
複数ユーザーで共有することで不安定になるような規模のシステムなら、すでにAccessではなく他のRDBを検討すべきだと思います。
あくまで私見ですので参考程度に。
以下に関しては私の推測です。試してみたわけではありまん。
まず、skさんの回答にもありましたがハイパーリンクの内部的な書式は下記になります。
ハイパーリンクを設定した非連結テキストボックスで、入力すると表示テキストのみになるのだと思われます。
つまりハイパーリンクアドレスは無し""という状態
対応策としては、ハイパーリンクアドレスがあればその前後に"#"を付ける。
なければ、表示テキストの前後に"#"を付ける。
このように状況、原因を調べて、対策を考えるという手順を踏みます。
あくまで、推測なのでこれでうまくいくとは限りません。
hatenaさん、長々とお付き合い頂いてありがとうございます。
skさんもありがとうございます!とても感謝しております!!
デバック方法については書籍を参考に試してみます。
特に急ぐようなことでは無いので、時間をかけて学習してみます。
ありがとうございました。
テーブル名 には実際にはどのような名前がはいってますか。
テーブル名に使用すべきでない文字が含まれているとそのようエラーになります。
そのような場合、名前の前後に"[" "]"を付けると回避できます。
下記のように変更したらどうでしょう。
可能ならばこのような特殊文字は使わないテーブル名に変更することをお勧めします。
Access データベースで特殊文字を使用したエラー - Microsoft 365 Apps | Microsoft Learn
skさんの#12の回答のSQLでどのような状態で格納されているか確認して、表示されない原因と対策を考えましょう。
私が思うに非連結でいくなら、テキストボックスの「ハイパーリンクあり」は「いいえ」に設定しておいた方がいいように思います。
実際にサンプルを作成して動作確認しているわけではないので、推測で提案しています。
非連結フォームの設計はかなりのスキルが要求されます。
連結でできていたものを、勉強のために非連結に変更しているということなので、
このような不具合を自分で解決できるようなスキルアップが必要ということです。
そのためにはまずはデバッグ方法を学習しましょう。
これを使って原因の追究、解決を繰り返すことによってスキルがアップします。
「VBA デバッグ」をキーワードにググれはいろいろ解説ページが見つかるので、
そこでデバッグの方法の理解を深めることをお勧めします。
hatenaさん
コンパイルエラーは解消されましたが、今度は直前にテキストボックスに入力したPC内のファイルパスが
更新ボタンをクリックしたと同時に消えてしまいます。私の書き方に問題ありますか?
何度もスミマセン。
今度は下記で「コンパイルエラー 変数が定義されていません」となりました。
If sAddress <> "" Then s = "#" & sAddress & "#"
あっ、すみません。タイプミスです。下記に修正してください。
If sAddress <> "" Then s = "#" & sAddress & "#"
私の 6 の回答でリンクを置いてます。
hatenaさん
提示していただいた文に差し替えてみたところ
「コンパイルエラー 変数が定義されていません」となり
If sAddress <> "" Then s = "#" & Address & "#"
となりました。
HyperlinkPartという関数、初め見たかもしれません。
勉強になります!
今回の場合はどちらでもいいでしょう。
例えば、特定の条件の場合はフォーカスさせずに別のコントロールにフォーカスさせたいというような場合は、取得時でないとだめですね。ただ、このような設計はたいてい悪手ですね。
特定の条件を満たすまで使用不可にしておくとか、、、ほかの方法を検討した方かいいです。
こんな感じでどうでしょうか。
下記の文ですと、パスの前後に"が付いた状態で書き込まれていました。
そして、修正文ありがとうございます。
早速試してみました。
遅くなりました。
まずは「T_特記事項」「T_クレーム履歴」に関するSELECT文です。
色々ありがとうございます。大変参考になりました。シンプルにサブフォームのコンボボックスに”Me!コンボ.Requery”でしまして上手くいきました。
参考にまで教えて欲しいのですが、この場合のフォーカスイベントは取得時の方がいいのでしょうか?取得後でも同じでしょうか? これの使い分けがよく分かってないもので。
そのように修正済みで、[特記詳細事項]の部分がURLということで、テキストボックスが「ハイパーリンクあり」かつ「ハイパーリンクである場合」の設定なら、
の部分を
でよさそうです。
あるいは、HyperlinkPart関数でアドレス部分のみ取り出して、
見当違いのコードを送ってしまい、
申し訳ありません。
該当コードは後ほどお送りします。
冒頭3でも書き込みましたが、
連結フォームで作って運用中のものを、
VBAの勉強を目的として取り組んでいる次第です。
その為、非連結となっております。
提示いただいたコードは、「T_機械設定」テーブルのデータを読み込んでいます。
質問のコードは、「T_特記事項」「T_クレーム履歴」への書き込みです。
「T_特記事項」「T_クレーム履歴」からの読み込みの部分のコードを提示してもらえますか。
あと、連結フォームでなく非連結フォームで読み込み、書き込みしている理由はなんでしょうか。
hatenaさん、ありがとうございます!
「btn_読込」に、下記のようなクリック時のイベント(一部抜粋)を設けて、格納させています。
その通りです。
既存レコードには、更新回数分であろう#が前後に増えていて、
レコードの無いところには、同じく更新回数分であろう#で埋め尽くされていました。
現時点ではレコード数も20件と少ないので、skさんからご提示して頂いたSQL文は使わず、
一個一個#を削除して、「#[特記詳細事項]#」のようなあるべき姿にしたところです。
悩ましいですねぇ
>> 2のhatenaさん提示の方法でいいと思いますが、個人的にはあまり
SetFocus
を使いたくないので別解も載せておきますACCESS VBA 別フォームのイベントを呼び出す方法(VBAコード公開)(たすけてACCESSさん)
(デフォルトで生成されるあれこれを弄るといろいろと混乱するので、
public
なそれ用のプロシージャを作るというのが、「hirotonならこうする」ですかね)の観点からなら
という方法もあります。が、プログラミング的な観点から同じ処理を別々な場所に記述するのは良くないので、今回の形なら「[tx文字]の更新後イベント」を発生させる方向が良いのでは、と思います
その他の方法として、「コンボボックスのリストが表示されるのはコンボボックスを使うとき」なので、コンボボックスのフォーカス取得時イベントで
Me!コンボ.Requery
を行うなんて手法もありますありがとうございました。その方法で出来ました。
こんな事が出来るとは知りませんでした、便利です。
お世話になりました。
色々と説明不足してました(すみません)。フォームAのサブフォームにあるコンボボックスの値集合ソースに Like "" & [Forms]![フォームAメイン]![tx文字] & "" としており絞り込みさせています。
フォームBが開かない場合には[tx文字]の更新後イベントに [サブフォーム].Form![コンボ].Requeryとしています。
要はこのRequeryをさせたいのです(フォームBからVBコードでフォームAメインの[tx文字]に代入)。
正確には、フォーカスをセットしておいて、Textプロパティに代入すると、更新イベントが発生します。
下記もご参考に。
値の代入で更新イベントを発生させる - hatena chips
ただし、hirotonさんも指摘されているように、コンボボックスのリストの絞り込みをどのようにしているかによります。
サブフォームが帳票フォームだったりするとさらに複雑な要因がでてきます。
上記の方法でうまくいけばいいですが、そうではない場合は、
絞り込みをどのようにしているのかと、コンボボックスは連結なのか、非連結なのか、サブフォームが帳票フォームなのか、、、などの情報が必要になります。
当方でサンプルを作成して確認してみましたが、症状は再現できませんでした。
パーションか環境に依存する症状だとするとこちらから原因を究明するのは難しいですね。
回避策としては、
条件付き書式を使わずに、VBAで背景色を変更するようにしてはどうでしょう。
コード例
詳細セクションのフォーマット時のイベントプロシージャに下記のように記述します。
上記は"回収"の場合、背景が黄色になります。
他の色を設定したい場合は、下記などを参考に。
Accessでコントロールの色を変える2つの方法|アズビーパートナーズ
そもそも
を、具体的にどのように行っていますか?
コンボボックスはそのコントロールソースに従って表示内容が決定されますが、もう少し具体的には、コントロールソースの内容を読み込むタイミングで決定されます。
そのタイミングの一つは、もちろん、「フォームを開いたとき」です。このタイミングでは特に気にすることなく自動で行われます。逆に言えば、通常これで十分なので、その他のタイミングで更新したい場合は「コントロールソースの読み込み直し処理」を自前で組まなければなりません
なので、上記指摘が「できている」のであれば「同じようにやればいい」です
こんな仕様はhirotonは知らないですね
(今回組んだシステムは)フォーカスセットをしておくと更新する(ように作ったのでフォーカスをセットすればいい)とかなら作れるかもしれません。(よくあると思います)
ならば、重要なのは、フォーカスをセットする方法ではなく、その時にどのような処理が行われるか?の方です。そこに「コントロールソースの読み込み直し処理」があると思います
プロパティを比べても相違はありませんでした。その後色々して分かった事があります。レポートに条件付き書式を設定すると、この現象になります。[区分]="回収"の時に塗りつぶし設定にしてます。レポート上のどのフィールドにその設定にすると#name?となります(ウィザードで作成した分も)。問題のあったレポートも条件付き書式を削除すると重複データ非表示になります。⇒条件付き書式と重複データ非表示を一緒に設定することは無理なのでしょうか?
了解です。回答に必須にな情報でした。
この「レコードを読み込ませる」とは具体的にどのように読み込ませているのでしょうか。
「非連結」なので、何かしないと何も表示されません。
『消えたレコードは「######・・・」と表示されました』ということは、UPDATE で前後に"#"を付加することを繰り返した結果でしょう(すでにskさんの回答で指摘されてます)。
誤った状態で保存されているのでまずはそれを修正する必要がありますね。
「######・・・」というのは、例えば「######https://zawazawa.jp/ms-access/######」というような表示でしょうか。(URL部分は一例)
とりあえずskさんの回答の12のSQLのクエリを作成して、それを開いてテーブルにどのような状態で格納されているか確認する必要があります。
すべたのレコードが「######https://zawazawa.jp/ms-access/######」というような状態(#の数はまちまちだがURLの前後に#)でしょうか。
それ以外の書式のものもありますか。あるなら、それを例示してください。
遅くなりました。
私の説明不足によりお二方には色々と推測させてしまい誠に申し訳ないです!
取り急ぎ、テキストボックスは「非連結」であり「ハイパーリンクあり」かつ「ハイパーリンクである場合」です。
試しに、このテキストボックスを「ハイパーリンクなし」に変換して、消えたレコードを読み込ませると
消えたレコードは「######・・・」と表示されました。
この該当テーブルのハイパーリンク型のフィールドを覗くと、「######・・・」であろうレコードはブランクでした。
hatenaさんが提示された通りコードを修正してみましたが、結果は「######・・・」となりました。
よろしくお願いします!
コードをどのように修正するかはともかくとして、テーブル[T_特記事項]のフィールド[特記事項詳細]、およびテーブル[T_クレーム履歴]のフィールド[クレーム詳細]の値が、現時点においてどのように格納されているのかについても、併せて確認された方がよいでしょう。
既に誤った形式のハイパーリンクが格納されてしまっているでしょうから、それらを修正する必要があります。
INSERT INTO の方は見落としてました。
どちらにしても、連結なのか、非連結なのか、
非連結ならハイパーリンクの設定がどうなっているのか、
まずはそれを明確にしてもらうのが先決ですね。
連結テキストボックスであれ非連結テキストボックスであれ、(ハイパーリンクの構文規則を無視して)無条件で「"#"で区切られた文字列」を更に"#"で囲んだ結果に更新する処理を繰り返し実行すれば、同様の結果がもたらされることは明白です。
もし非連結テキストボックスであるならば、恐らくそれらのテキストボックスの[ハイパーリンクあり]プロパティを「はい」、[ハイパーリンクとして表示]プロパティを「ハイパーリンクである場合」か「常にハイパーリンクにする」に設定されているだと思われますが、そのテキストボックスに"
###https://zawazawa.jp/ms-access/###
"のような文字列を代入すれば、画面表示上は「何も表示されていない」状態となるでしょう。質問文より
このテキストボックスがハイパーリンク型フィールドとの連結コントロールだとしたらskさんの通りですね。
私としては、
1から10の連番の付加された10個のテキストボックスである、
SQLでは追加するテーブル側のフィールドは一つである、
ということからこのテキストボックスは非連結コントロールだろうと推測してます。
「サブフォームにある"T_特記事項"と"T_クレーム履歴"には」という表現が連結フォームを連想させるのが紛らわしいですが。
また、[txt_詳細リンク]および[txt_クレーム詳細リンク]が連結テキストボックスではなく非連結テキストボックスであるならば、INSERT INTO ... VALUES ... 文の実行結果も適切ではない可能性があります。
"#"で区切られていない文字列をそのまま代入しているなら、ハイパーリンクの構文上においては「表示テキストのみが設定されている(ハイパーリンクアドレスが2番目ではなく1番目のセクションに入っている)」状態になっているはず。
#name? となるのは、重複データ非表示にしたテキストボックスですか。
ウィザードで作成した簡易なレポートの正常に表示されるテキストボックスと #name? となるテキストボックスのプロパティの設定で異なる部分はないですか。
異なる部分があったら、それを正常な方に合わせたらどうなりますか。
ハイパーリンク型の実体とは、「ハイパーリンク属性を付与されたメモ型(長いテキスト)」である。
ハイパーリンク型の内部処理上の値は、"#" をセクション区切り記号(囲み記号ではない)とした最大4つのセクションで構成された文字列である。
仮に[txt_詳細リンク]および[txt_クレーム詳細リンク]が共にハイパーリンク型のフィールドをコントロールソースとする連結テキストボックスであるとした場合、そのフィールドの値を"#"で囲む(厳密には「先頭に"#"を挿入する」)という操作は、ハイパーリンクの各セクションを1つ右のセクションにずらすことと同義である。
したがって、件の UPDATE 文が繰り返し実行されれば、やがてハイパーリンクの表示テキスト、ハイパーリンクアドレス、サブアドレスが全て空の状態となり、表示上は「パスが消えてしまう」かのように見えてしまうことになる。
その後ウィザードで作成した分のページヘッダーのラベルと詳細セクション部を削除して問題あるレポートからそれらをコピーしました⇒やはり重複データ非表示にすると#name?となります(いいえにすると全て表示)
ますます不思議です。
ハイパーリンク型フィールドのURLは"#"で囲むのが仕様だと思います。
Access Tips #526 ハイパーリンク型フィールドにSQLでデータを保存するには? | T'sWare
Application.HyperlinkPart メソッド (Access) | Microsoft Learn