Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
If Me.区分.Value = "回収" Then
Me.テキストボックス名.BackColor = vbYellow
Else
Me.テキストボックス名.BackColor = vbWhite
End If
End Sub
Function tryExecute(sqlList As Collection) As String
'## 複数のSQLを実行するFunctionプロシージャ(SQLリストをすべて実行してメッセージを受け取る関数)
'エラーが起きたら「ErrorHandler」へジャンプ
On Error GoTo ErrorHandler
Dim daoWs As DAO.Workspace
Set daoWs = DBEngine(0) 'トランザクションをサポートするオブジェクトを作成
Dim daoDb As DAO.Database
Set daoDb = CurrentDb '接続
daoWs.BeginTrans 'トランザクション開始
Dim strSQL As Variant
For Each strSQL In sqlList 'SQL文リストをループ
daoDb.Execute strSQL '実行
Next strSQL
daoWs.CommitTrans '確定
'成功の場合は空の文字列が入る
tryExecute = ""
'接続解除へジャンプ
GoTo Finally
'エラー処理
ErrorHandler:
tryExecute = "Error #: " & Err.Number & vbNewLine & vbNewLine & Err.Description 'エラーの場合はエラーメッセージが入る
'接続解除
Finally:
If Not daoDb Is Nothing Then
daoDb.Close
Set daoDb = Nothing
End If
If Not daoWs Is Nothing Then 'トランザクション用のオブジェクトを破棄
daoWs.Close
Set daoWs = Nothing
End If
End Function
何度もスミマセン。
今度は下記で「コンパイルエラー 変数が定義されていません」となりました。
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
ありがとうございます。対象レポートソースの集計クエリの基もクエリ(A)にしてまして、その(A)をソースにしたレポートも同じ状態でした(以前作成)。その(A)を使いウィザードで簡易なレポート作成すると問題なく重複データ非表示は出来ています。不思議です。何かの設定でしょうか?
上記のコードで、詳細リンクがNullの場合、""(空文字列)に変換しています。
下記の次のコードで、
IsNullでNullかどうかをチェックしていますが、その前でNullは""に変換されてますので、このSQLは必ず実行されます。
つまり、""に更新されてしまう。これが下記の原因かと思います。
対策としては、前者のコードは削除して、後者のコードを下記に修正すればどうでしょうか。
上記以外の該当部分も同様に修正してください。
あと、コスト、ですかね。
案件や状況によりけり、としか言えないのが難しいところですね。
質問内容が「Accessについてどのような意見を持っているか」なので、日頃Accessを選択する場合の理由になることを書いてみました。
やはり小~中の企業でシステム周りにあまりお金をかけたくない、というところは多くそういった場合に提案されることはまだまだ続くと思います。
SEから見ればコスト度外視で開発が楽な環境にしてくれとなるでしょう。質問にある指摘はそれだけとは言いませんがその面が大きく出ているように思いますね
企業から見れば、企業の実態に見合ったシステムの要件と、コスト(導入コスト・ランニングコスト)、時間(開発時間や運用に関する時間(これは≒システム要件))が問題です。開発・メンテナンスのしやすさなんてものは評価に値しません
それらは全てひっくるめて結局、できるのか?いつまでに?いくらで?で判断されることです
会社の大小によって、これらの評価の閾値はかわるでしょうが、これらが評価項目であることに変わりはないでしょう
ACCESSは貧弱なのでシステムの要件という大前提のもとNGとなる場合もあります。「要求を十分に満たす」となればコストパフォーマンスは高いと思います
実際、大掛かりなシステムでもフロントエンド(の一部はACCESS)という場合もあります
繰り返しますが、ACCESSは特定の条件に於いて「十分である」という評価をつけることはあります。これは「よい」ではありませんし、なんなら、大規模化を望めないという観点から「よくない」とするのが一般的な評価ではないか?というのがhirotonの考えです
まぁ、「一般的」などという特殊な環境なんてそうそうないとも思ってますが
ACCESSとVBAは切っても切れない関係ですが、同一のものではありません。VBAだけなら覚えなくてもいいんじゃないかなぁとも思います。ACCESSを使うなら覚えないわけにはいかないですが
時代は「クラウド」で「ノーコード」で「RPA」だ、なんで、いままで「office」で「VBA」でなんて言っていたのは今や特別必要というわけでもないのでしょう
ACCESSのような「手軽さ」も特別感のあるものではなくなってきました。ACCESSがいらないのであれば、必然VBAの必要性も無くなります
hirotonのまわりはまだまだサブスクリプションに拒否感を受ける人も多いようで、「スタンドアロン」で「買い切り」で、が決め手になる場合もありますが、システム選定の幅はかなり広がっていると思います。「同等の知識はあるが、ACCESSやVBAは知らない」という人がいてもおかしくない時代じゃないでしょうか
余談
VBAの兄弟分でもあるVBScriptがとうとう非推奨になってしまいました
https://learn.microsoft.com/en-us/windows/whats-new/deprecated-features-resources#vbscript
VBA,VBScriptの手軽さ、便利さはWindowsを使うにあたって有用なものだったんですが、そういう付加価値もなくなってくるとやはり、VBAにも消極的な姿勢にならざるを得ないかなぁと感じています
会社の規模感と開発に携わる人数の問題なんですかね。
"#"で囲っているのが余計だからでしょう。
一度、連結フォームで作成したものを書籍を参考にVBAでチャレンジしています。
2つのハイパーリンク型のフィールド以外は、難なく更新できています。
複数のSQL実行のためのプロシージャ
一部を略しましたが、更新文です。