Microsoft Access 掲示板

UPDATEする度にレコードが消えてしまいます

33 コメント
views
4 フォロー

AccessおよびVBAを勉強しています。
UPDATE文について質問します。
サブフォームにある"T_特記事項"と"T_クレーム履歴"には、それぞれ10個のテキストボックスがあって、
そこにPC上の関連ファイルのパスを入力して、ハイパーリンク型フィールド"特記事項詳細"と"クレーム詳細"に
UPDATEをしたいのですが、更新の度に直前にUPDATEしたパスが消えてしまう現象が出ました。
Debug"1"、Debug"2"を使って確認しましたが、イミディエイトウィンドウには順当に1が10個、2が10個出力されました。
他所で同じ質問をして、Null、"" 、" "とでは違うのだという指摘をもらっています。
http://access2genzo.blog6.fc2.com/blog-entry-37.html
↑コチラに書いていることと同様の指摘だと認識しているのですが、
私の文の作り方が悪いのか?うまく走りませんでした。
どうしたら、直前までのレコードが消えなくなるのか?ご教授いただけたらと思います。

  Dim R As Long
  For R = 1 To 10
  
  If IsNull(Me("txt_詳細リンク" & R).Value) Then
    Me("txt_詳細リンク" & R).Value = Nz((Me("txt_詳細リンク" & R).Value), "")
  End If
  Debug.Print "1"
  If Not IsNull(Me("txt_特記ID" & R).Value) Then

    strSQL = _
      "UPDATE T_特記事項 " & _
      "SET " & _
        "口座番号 = '" & Me.txt_口座番号.Value & "', " & _
        "特記事項 = '" & Me("txt_特記事項" & R).Value & "', " & _
        "特記事項詳細 = '#" & Replace(Me("txt_詳細リンク" & R).Value, """", "") & "#' " & _
      "WHERE ID = " & Me("txt_特記ID" & R).Value & ";"
      sqlList.Add strSQL
  ElseIf Not IsNull(Me("txt_特記事項" & R).Value) Then
    strSQL = _
      "INSERT INTO T_特記事項 (口座番号, 特記事項, 特記事項詳細) " & _
      "VALUES" & _
        "('" & Me.txt_口座番号.Value & "', " & _
        "'" & Me("txt_特記事項" & R).Value & "', " & _
        "'" & Me("txt_詳細リンク" & R).Value & "');"
      sqlList.Add strSQL
    End If
  Next R
  
  Dim Z As Long
  For Z = 1 To 10
  Debug.Print "2"
  If IsNull(Me("txt_クレーム詳細リンク" & Z).Value) Then
    Me("txt_クレーム詳細リンク" & Z).Value = Nz((Me("txt_クレーム詳細リンク" & Z).Value), "")
  End If
  
  If Not IsNull(Me("txt_クレームID" & Z).Value) Then

    strSQL = _
      "UPDATE T_クレーム履歴 " & _
      "SET " & _
        "口座番号 = '" & Me.txt_口座番号.Value & "', " & _
        "発生年月 = '" & Me("txt_発生年月" & Z).Value & "', " & _
        "クレーム内容 = '" & Me("txt_クレーム内容" & Z).Value & "', " & _
        "是正処置 = '" & Me("txt_是正処置" & Z).Value & "', " & _
        "クレーム詳細 = '#" & Replace(Me("txt_クレーム詳細リンク" & Z).Value, """", "") & "#' " & _
      "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
  
wazawaza
作成: 2024/01/30 (火) 18:52:36
最終更新: 2024/01/30 (火) 18:53:49
通報 ...
1
wazawaza 2024/01/31 (水) 09:04:24

一部を略しましたが、更新文です。


Private Sub btn_更新_Click()
  Dim sqlList As Collection
  Set sqlList = New Collection  'コレクションを作成
  
  〜省略〜

  Dim R As Long
  For R = 1 To 10
  
  If IsNull(Me("txt_詳細リンク" & R).Value) Then
    Me("txt_詳細リンク" & R).Value = Nz((Me("txt_詳細リンク" & R).Value), "")
  End If
  Debug.Print "1"
  If Not IsNull(Me("txt_特記ID" & R).Value) Then '「txt_特記ID」が空でなければ
    strSQL = _
      "UPDATE T_特記事項 " & _
      "SET " & _
        "口座番号 = '" & Me.txt_口座番号.Value & "', " & _
        "特記事項 = '" & Me("txt_特記事項" & R).Value & "', " & _
        "特記事項詳細 = '#" & Replace(Me("txt_詳細リンク" & R).Value, """", "") & "#' " & _
      "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
  
  Dim Z As Long
  For Z = 1 To 10
  Debug.Print "2"
  If IsNull(Me("txt_クレーム詳細リンク" & Z).Value) Then
    Me("txt_クレーム詳細リンク" & Z).Value = Nz((Me("txt_クレーム詳細リンク" & Z).Value), "")
  End If
  
  If Not IsNull(Me("txt_クレームID" & Z).Value) Then  '「txt_クレームID」が空でなければ
  '実行
    strSQL = _
      "UPDATE T_クレーム履歴 " & _
      "SET " & _
        "口座番号 = '" & Me.txt_口座番号.Value & "', " & _
        "発生年月 = '" & Me("txt_発生年月" & Z).Value & "', " & _
        "クレーム内容 = '" & Me("txt_クレーム内容" & Z).Value & "', " & _
        "是正処置 = '" & Me("txt_是正処置" & Z).Value & "', " & _
        "クレーム詳細 = '#" & Replace(Me("txt_クレーム詳細リンク" & Z).Value, """", "") & "#' " & _
      "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
  
  Dim errMsg As String
  errMsg = tryExecute(sqlList)  'SQLリストを実行してメッセージを受け取る
  
  If errMsg <> "" Then  'メッセージが空ではない(エラーがあった)場合
    MsgBox errMsg, vbCritical, "エラー" '受け取ったメッセージを出力
    Exit Sub  '終了
  End If
  
  Call loadForm  '読込を呼び出す
  MsgBox "更新しました", vbInformation, "完了" 'メッセージを出力
  DoCmd.Close acForm, "F_作業標準入力", acSaveNo
End Sub
2
wazawaza 2024/01/31 (水) 09:07:23

複数のSQL実行のためのプロシージャ


 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


3
wazawaza 2024/01/31 (水) 09:10:27

一度、連結フォームで作成したものを書籍を参考にVBAでチャレンジしています。
2つのハイパーリンク型のフィールド以外は、難なく更新できています。

4

ハイパーリンク型フィールド"特記事項詳細"と"クレーム詳細"に
UPDATEをしたいのですが、更新の度に直前にUPDATEしたパスが消えてしまう

"特記事項詳細 = '#" & Replace(Me("txt_詳細リンク" & R).Value, """", "") & "#' "
"クレーム詳細 = '#" & Replace(Me("txt_クレーム詳細リンク" & Z).Value, """", "") & "#' "

"#"で囲っているのが余計だからでしょう。

7
  • ハイパーリンク型の実体とは、「ハイパーリンク属性を付与されたメモ型(長いテキスト)」である。

  • ハイパーリンク型の内部処理上の値は、"#" をセクション区切り記号(囲み記号ではない)とした最大4つのセクションで構成された文字列である。

表示テキスト#ハイパーリンクアドレス#サブアドレス#ヒントテキスト

画像1

  • 仮に[txt_詳細リンク]および[txt_クレーム詳細リンク]が共にハイパーリンク型のフィールドをコントロールソースとする連結テキストボックスであるとした場合、そのフィールドの値を"#"で囲む(厳密には「先頭に"#"を挿入する」)という操作は、ハイパーリンクの各セクションを1つ右のセクションにずらすことと同義である。

  • したがって、件の UPDATE 文が繰り返し実行されれば、やがてハイパーリンクの表示テキスト、ハイパーリンクアドレス、サブアドレスが全て空の状態となり、表示上は「パスが消えてしまう」かのように見えてしまうことになる。

8

また、[txt_詳細リンク]および[txt_クレーム詳細リンク]が連結テキストボックスではなく非連結テキストボックスであるならば、INSERT INTO ... VALUES ... 文の実行結果も適切ではない可能性があります。

"#"で区切られていない文字列をそのまま代入しているなら、ハイパーリンクの構文上においては「表示テキストのみが設定されている(ハイパーリンクアドレスが2番目ではなく1番目のセクションに入っている)」状態になっているはず。

9

質問文より

サブフォームにある"T_特記事項"と"T_クレーム履歴"には、それぞれ10個のテキストボックスがあって、
そこにPC上の関連ファイルのパスを入力して、ハイパーリンク型フィールド"特記事項詳細"と"クレーム詳細"に
UPDATEをしたいのですが、

このテキストボックスがハイパーリンク型フィールドとの連結コントロールだとしたらskさんの通りですね。

私としては、
1から10の連番の付加された10個のテキストボックスである、
SQLでは追加するテーブル側のフィールドは一つである、
ということからこのテキストボックスは非連結コントロールだろうと推測してます。

「サブフォームにある"T_特記事項"と"T_クレーム履歴"には」という表現が連結フォームを連想させるのが紛らわしいですが。

10

1から10の連番の付加された10個のテキストボックスである、
SQLでは追加するテーブル側のフィールドは一つである、
ということからこのテキストボックスは非連結コントロールだろうと推測してます。

連結テキストボックスであれ非連結テキストボックスであれ、(ハイパーリンクの構文規則を無視して)無条件で「"#"で区切られた文字列」を更に"#"で囲んだ結果に更新する処理を繰り返し実行すれば、同様の結果がもたらされることは明白です。

もし非連結テキストボックスであるならば、恐らくそれらのテキストボックスの[ハイパーリンクあり]プロパティを「はい」、[ハイパーリンクとして表示]プロパティを「ハイパーリンクである場合」か「常にハイパーリンクにする」に設定されているだと思われますが、そのテキストボックスに"###https://zawazawa.jp/ms-access/###"のような文字列を代入すれば、画面表示上は「何も表示されていない」状態となるでしょう。

11
hatena 2024/01/31 (水) 16:08:24 修正 >> 6

INSERT INTO の方は見落としてました。

どちらにしても、連結なのか、非連結なのか、
非連結ならハイパーリンクの設定がどうなっているのか、
まずはそれを明確にしてもらうのが先決ですね。

12

コードをどのように修正するかはともかくとして、テーブル[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];
5
  If IsNull(Me("txt_詳細リンク" & R).Value) Then
    Me("txt_詳細リンク" & R).Value = Nz((Me("txt_詳細リンク" & R).Value), "")
  End If

上記のコードで、詳細リンクがNullの場合、""(空文字列)に変換しています。
下記の次のコードで、

  If Not IsNull(Me("txt_特記ID" & R).Value) Then '「txt_特記ID」が空でなければ
    strSQL = _
      "UPDATE T_特記事項 " & _
      "SET " & _
        "口座番号 = '" & Me.txt_口座番号.Value & "', " & _
        "特記事項 = '" & Me("txt_特記事項" & R).Value & "', " & _
        "特記事項詳細 = '#" & Replace(Me("txt_詳細リンク" & R).Value, """", "") & "#' " & _
      "WHERE ID = " & Me("txt_特記ID" & R).Value & ";"
      sqlList.Add strSQL

IsNullでNullかどうかをチェックしていますが、その前でNullは""に変換されてますので、このSQLは必ず実行されます。
つまり、""に更新されてしまう。これが下記の原因かと思います。

更新の度に直前にUPDATEしたパスが消えてしまう

対策としては、前者のコードは削除して、後者のコードを下記に修正すればどうでしょうか。

  If Nz(Me("txt_特記ID" & R).Value, "") <> "" Then '「txt_特記ID」が空でなければ
    strSQL = _
      "UPDATE T_特記事項 " & _
      "SET " & _
        "口座番号 = '" & Me.txt_口座番号.Value & "', " & _
        "特記事項 = '" & Me("txt_特記事項" & R).Value & "', " & _
        "特記事項詳細 = '#" & Replace(Me("txt_詳細リンク" & R).Value, """", "") & "#' " & _
      "WHERE ID = " & Me("txt_特記ID" & R).Value & ";"
      sqlList.Add strSQL

上記以外の該当部分も同様に修正してください。

13
wazawaza 2024/01/31 (水) 20:05:27

遅くなりました。
私の説明不足によりお二方には色々と推測させてしまい誠に申し訳ないです!

取り急ぎ、テキストボックスは「非連結」であり「ハイパーリンクあり」かつ「ハイパーリンクである場合」です。
試しに、このテキストボックスを「ハイパーリンクなし」に変換して、消えたレコードを読み込ませると
消えたレコードは「######・・・」と表示されました。
この該当テーブルのハイパーリンク型のフィールドを覗くと、「######・・・」であろうレコードはブランクでした。

hatenaさんが提示された通りコードを修正してみましたが、結果は「######・・・」となりました。

よろしくお願いします!

14

取り急ぎ、テキストボックスは「非連結」であり「ハイパーリンクあり」かつ「ハイパーリンクである場合」です。

了解です。回答に必須にな情報でした。

試しに、このテキストボックスを「ハイパーリンクなし」に変換して、消えたレコードを読み込ませると
消えたレコードは「######・・・」と表示されました。

この「レコードを読み込ませる」とは具体的にどのように読み込ませているのでしょうか。
「非連結」なので、何かしないと何も表示されません。

『消えたレコードは「######・・・」と表示されました』ということは、UPDATE で前後に"#"を付加することを繰り返した結果でしょう(すでにskさんの回答で指摘されてます)。
誤った状態で保存されているのでまずはそれを修正する必要がありますね。

「######・・・」というのは、例えば「######https://zawazawa.jp/ms-access/######」というような表示でしょうか。(URL部分は一例)

とりあえずskさんの回答の12のSQLのクエリを作成して、それを開いてテーブルにどのような状態で格納されているか確認する必要があります。

すべたのレコードが「######https://zawazawa.jp/ms-access/######」というような状態(#の数はまちまちだがURLの前後に#)でしょうか。
それ以外の書式のものもありますか。あるなら、それを例示してください。

15
wazawaza 2024/02/01 (木) 18:21:30

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部分は一例)

その通りです。
既存レコードには、更新回数分であろう#が前後に増えていて、
レコードの無いところには、同じく更新回数分であろう#で埋め尽くされていました。

現時点ではレコード数も20件と少ないので、skさんからご提示して頂いたSQL文は使わず、
一個一個#を削除して、「#[特記詳細事項]#」のようなあるべき姿にしたところです。

16

提示いただいたコードは、「T_機械設定」テーブルのデータを読み込んでいます。
質問のコードは、「T_特記事項」「T_クレーム履歴」への書き込みです。
「T_特記事項」「T_クレーム履歴」からの読み込みの部分のコードを提示してもらえますか。

あと、連結フォームでなく非連結フォームで読み込み、書き込みしている理由はなんでしょうか。

17
wazawaza 2024/02/02 (金) 04:09:17

見当違いのコードを送ってしまい、
申し訳ありません。
該当コードは後ほどお送りします。

冒頭3でも書き込みましたが、
連結フォームで作って運用中のものを、
VBAの勉強を目的として取り組んでいる次第です。
その為、非連結となっております。

18

現時点ではレコード数も20件と少ないので、skさんからご提示して頂いたSQL文は使わず、
一個一個#を削除して、「#[特記詳細事項]#」のようなあるべき姿にしたところです。

そのように修正済みで、[特記詳細事項]の部分がURLということで、テキストボックスが「ハイパーリンクあり」かつ「ハイパーリンクである場合」の設定なら、

"特記事項詳細 = '#" & Replace(Me("txt_詳細リンク" & R).Value, """", "") & "#' "

の部分を

"特記事項詳細 = '" & Me("txt_詳細リンク" & R).Value & "'"

でよさそうです。
あるいは、HyperlinkPart関数でアドレス部分のみ取り出して、

"特記事項詳細 = '#" & HyperlinkPart(Me("txt_詳細リンク" & R).Value, acAddress) & "#' "
19
wazawaza 2024/02/02 (金) 10:33:27

遅くなりました。
まずは「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

20
wazawaza 2024/02/02 (金) 10:37:49

そして、修正文ありがとうございます。
早速試してみました。

"特記事項詳細 = '#" & HyperlinkPart(Me("txt_詳細リンク" & R).Value, acAddress) & "#' "

上記の文に修正をして、更新してみたところ
アドレス(パス)を書き込むことが出来ました。
が、ブランクのレコードには「##」と書かれていました。
21
wazawaza 2024/02/02 (金) 10:40:27

下記の文ですと、パスの前後に"が付いた状態で書き込まれていました。

"特記事項詳細 = '" & Me("txt_詳細リンク" & R).Value & "'"
22

こんな感じでどうでしょうか。

  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
23
wazawaza 2024/02/02 (金) 15:46:27

hatenaさん
提示していただいた文に差し替えてみたところ
「コンパイルエラー 変数が定義されていません」となり
If sAddress <> "" Then s = "#" & Address & "#"
となりました。

HyperlinkPartという関数、初め見たかもしれません。
勉強になります!

24

「コンパイルエラー 変数が定義されていません」となり
If sAddress <> "" Then s = "#" & Address & "#"
となりました。

あっ、すみません。タイプミスです。下記に修正してください。
If sAddress <> "" Then s = "#" & sAddress & "#"

HyperlinkPartという関数、初め見たかもしれません。

私の 6 の回答でリンクを置いてます。

25
wazawaza 2024/02/03 (土) 13:57:11

何度もスミマセン。
今度は下記で「コンパイルエラー 変数が定義されていません」となりました。
If sAddress <> "" Then s = "#" & sAddress & "#"

26
If sAddress <> "" Then sAddress = "#" & sAddress & "#"
27
wazawaza 2024/02/03 (土) 23:54:21

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

28

コンパイルエラーは解消されましたが、今度は直前にテキストボックスに入力したPC内のファイルパスが
更新ボタンをクリックしたと同時に消えてしまいます。

skさんの#12の回答のSQLでどのような状態で格納されているか確認して、表示されない原因と対策を考えましょう。

私が思うに非連結でいくなら、テキストボックスの「ハイパーリンクあり」は「いいえ」に設定しておいた方がいいように思います。


実際にサンプルを作成して動作確認しているわけではないので、推測で提案しています。

非連結フォームの設計はかなりのスキルが要求されます。
連結でできていたものを、勉強のために非連結に変更しているということなので、
このような不具合を自分で解決できるようなスキルアップが必要ということです。
そのためにはまずはデバッグ方法を学習しましょう。
これを使って原因の追究、解決を繰り返すことによってスキルがアップします。
「VBA デバッグ」をキーワードにググれはいろいろ解説ページが見つかるので、
そこでデバッグの方法の理解を深めることをお勧めします。

29
wazawaza 2024/02/05 (月) 14:56:28 修正

hatenaさん、長々とお付き合い頂いてありがとうございます。
skさんもありがとうございます!とても感謝しております!!
デバック方法については書籍を参考に試してみます。
特に急ぐようなことでは無いので、時間をかけて学習してみます。
ありがとうございました。

31

コンパイルエラーは解消されましたが、今度は直前にテキストボックスに入力した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

このように状況、原因を調べて、対策を考えるという手順を踏みます。
あくまで、推測なのでこれでうまくいくとは限りません。

32

非連結フォームの設計は、連結フォームならAccessが自動でいろいろしてくれていることをすべて自前で処理する必要がでてきます。
非連結で設計するということは、このAccessが裏でやっていてくれてることを理解、把握しておく必要があります。

ハイパーリンクは格納されているデータと表示されているテキストが一致していないというのが、難しくなる原因です。
他にも日付/時刻型もそうです。

他にも型チェック、参照整合性チェックなど、考慮しなければならないことか多数あります。
複数ユーザーで共有する場合、排他処理なども必要になってきます。

これらのことをすべて実装するとなるとなまはんかのスキルでは無理です。
これらを実装できたとして、連結にくらべてどれほどのメリットがあるのかはなはだ疑問なので、
私自身は非連結はほとんど使いません。

複数ユーザーで共有する場合は、安定性を高めるために非連結にすべきという意見も散見しますが、
上記の点についての言及はほとんど見ません。

複数ユーザーで共有することで不安定になるような規模のシステムなら、すでにAccessではなく他のRDBを検討すべきだと思います。
あくまで私見ですので参考程度に。

33
wazawaza 2024/02/06 (火) 10:58:06

hatenaさん
先程ご提示していただいた文で、問題解決出来ました!!
ありがとうございます!

ハイパーリンクを設定した非連結テキストボックスで、入力すると表示テキストのみになるのだと思われます。
つまりハイパーリンクアドレスは無し""という状態

ハイパーリンクの構造を理解していない上に、非連結を使って入力をした事で混乱を招いてしまったのですね...。
申し訳ございませんでした。

他にも型チェック、参照整合性チェックなど、考慮しなければならないことか多数あります。
複数ユーザーで共有する場合、排他処理なども必要になってきます。
これらのことをすべて実装するとなるとなまはんかのスキルでは無理です。
これらを実装できたとして、連結にくらべてどれほどのメリットがあるのかはなはだ疑問なので、
私自身は非連結はほとんど使いません。
複数ユーザーで共有する場合は、安定性を高めるために非連結にすべきという意見も散見しますが、
上記の点についての言及はほとんど見ません。

VBA関連の書籍のキャッチフレーズに「現場で即使える」と謳われるものが沢山ありますが
現場から要求されるリクエストは、書籍に載っていないものが圧倒的多いように感じますので
hatenaさんの仰る通り、全ての要求に応えられるにはハイレベルのスキルが求められますね。

今回はハイパーリンクについて、hatenaさん・skさんに沢山学ばせていただきました。
長々とお付き合いいただき、改めてお礼申し上げます!ありがとうございます!

まだまだ聞きたいことは沢山あるのですが、それはまた改めて聞きたいと思います。
ありがとうございました!!これからもよろしくお願いいたします!