Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


1078 / 2272 ツリー ←次へ | 前へ→

【8868】履歴について アイマール 06/12/6(水) 19:30 質問[未読]
【8871】Re:履歴について 小僧 06/12/7(木) 14:42 発言[未読]
【8872】Re:履歴について アイマール 06/12/7(木) 15:48 質問[未読]
【8873】Re:履歴について 小僧 06/12/7(木) 16:16 発言[未読]
【8875】Re:履歴について アイマール 06/12/7(木) 16:53 質問[未読]
【8877】Re:履歴について 小僧 06/12/7(木) 17:50 発言[未読]

【8868】履歴について
質問  アイマール  - 06/12/6(水) 19:30 -

引用なし
パスワード
   Q_住所(クエリ)を元に作成したフォームがあり、そのフォームには、
「姓」、「名」、「No_組織」、「No_テスト」など、各フィールドを
貼っています。

◇テキストボックス:「姓」、「名」、その他・・・
◇コンボボックス:「No_組織」、「No_テスト」、その他・・・

それらのコントロールにて、何かを編集したら、編集前のレコードを、
履歴用テーブルに記録したい。
つまり、Q_住所のレコードを、履歴用テーブルに記録する。

<目的>
ただし、どの"フィールド"を修正したか、フィールド名も記録するため、
編集前のフィールドと編集後のフィールドを比較したい。

<エラー>
テキストボックスとコンボボックスを貼っている場合、両方を編集したら
何故かエラーが出ます。
尚、何故か、テキストボックスのみ編集した場合はエラーは起きませんでした。
何か足りない部分がありますでしょうか??

ctl_Nameにて、編集したフィールド名を格納するものとし、
MsgBox ctl_Name にて、編集したフィールド名を確認しています。


下記、プログラムの、
    If ctlTextbox.ControlType = acTextBox Or ctlTextbox.ControlType = acComboBox Then
の部分で、
「この操作は、このタイプのオブジェクトには実行できません」とエラーが起きてしまいます。
何故、このような現象が起きるか分かりませんので、教えて下さい。
(過去ログも見ましたが、それらしきものは見つかりませんでした)

「姓」、「名」のみ編集した場合は、何もエラーが起きず、姓, 名 と
記録されますが、コンボボックス「姓」、「No_組織」を編集した場合は、
上記のようなエラーが出てしまいます。

--------------処理プログラム----------------------------
  ctl_Name = Null 'Variantなので、初期値Null
  'コントロール名(フィールド名)の取得
  For Each ctlTextbox In Me.Controls
    'コントロールがテキストボックスとコンボボックスである
    If ctlTextbox.ControlType = acTextBox Or ctlTextbox.ControlType = acComboBox Then
      '更新前データと更新後データを比較
      If Nz(ctlTextbox.OldValue) <> Nz(ctlTextbox.Value) Then
        'コントロール名をctl_Name に格納
        If IsNull(ctl_Name) Then 'ctl_Nameが空白の場合
          ctl_Name = ctlTextbox.Name
          'ctl_Name = ControlsSorce.Name '意味不明なプログラム記述
        Else
          ctl_Name = ctl_Name & "," & Chr(32) & Chr(32) & ctlTextbox.Name
        End If
      End If
    End If
  Next ctlTextbox
  MsgBox ctl_Name

【8871】Re:履歴について
発言  小僧  - 06/12/7(木) 14:42 -

引用なし
パスワード
   ▼アイマール さん:
こんにちは。

まず…他人に見せるプログラムなのですから
最低限の読みやすさは考慮しましょうね。

宣言部は提示していない、
また「ctlTextbox」という変数名から

Dim ctlTextbox As Access.Textbox

という宣言が隠れていると推測するのが普通だと思われます。
その後の

> ctlTextbox.ControlType = acComboBox Then


という記述で何かおかしいな…と気づく訳です。

どこかのサイトを参考にしてアイマールさんなりに
試行錯誤したプログラムなのかもしれませんが、
他人に見てもらうからには推測しやすい変数名にするか
変数の宣言部分を提示するかをしないと適切な回答が得られませんよ^^


さて、本題なのですが

エラー発生時において、ctlTextbox という変数の中には
どのコントロールが入っているのでしょうか。
ControlType プロパティがないコントロールというのは余り聞いた事がないですね。
もし、

> If Nz(ctlTextbox.OldValue) <> Nz(ctlTextbox.Value) Then

の行でエラーが発生している、という事でしたら
OldValueプロパティ や Value プロパティを持っていない
コントロールによってエラーが出ていると推測できるのですが…。

【8872】Re:履歴について
質問  アイマール  - 06/12/7(木) 15:48 -

引用なし
パスワード
   確かにおっしゃる通りです。
分かりやすい変数名に変更させて頂きました。
Dim ctl As Control
Dim ctl_FieldName As Variant

>Dim ctl As Access.Textbox
ではなく、

Dim ctl As Control

と宣言しております

> ctl.ControlType = acComboBox Then
> という記述で何かおかしいな…と気づく訳です。

If ctl.ControlType = acTextBox Or ctl.ControlType = acComboBox Or ctl.ControlType = acCheckBox Then
と記述して、見た感じは間違いはないように感じます。(チェックボックスが漏れていました)
ctl As Control と宣言しているんですが、どこに間違いがあるのでしょうか・・・。

テキストボックスのみ編集した場合もあれば、テキストボックスとチェックボックスを編集した場合もあれば、
コンボボックスのみ編集する場合もあります。それぞれです。

> エラー発生時において、ctl という変数の中には
> どのコントロールが入っているのでしょうか。

あるクエリを元に貼り付けたコントロールの種類は「テキストボックス」、「コンボボックス」、
「チェックボックス」の3つのみです。
したがって、ctlの変数には上の3つのコントロールが入っていると思いますが、如何でしょうか。


下記プログラムで試しても、If Nz(ctl.OldValue) <> Nz(ctl.Value) Thenで
エラーが起きてしまいます。
テキストボックスのみ編集した場合は何故か、問題ありませんが、両方を編集した場合は、
エラーが起きてしまいます。

------------------------------------------------------
Dim ctl As Control
Dim ctl_FieldName As Variant
  
ctl_FieldName = Null 'Variantなので、初期値Null
'コントロール名(フィールド名)の取得
For Each ctl In Me.Controls
'コントロールがテキストボックスである
 If ctl.ControlType = acTextBox Or ctl.ControlType = acComboBox Or ctl.ControlType = acCheckBox Then
  '更新前データと更新後データを比較
  If Nz(ctl.OldValue) <> Nz(ctl.Value) Then
   'コントロール名をctl_FieldName に格納
   If IsNull(ctl_FieldName) Then
    ctl_FieldName = ctl.Name
   Else
    ctl_FieldName = ctl_FieldName & "," & Chr(32) & Chr(32) & ctl.Name
   End If
  End If
 End If
Next ctl
MsgBox ctl_FieldName

【8873】Re:履歴について
発言  小僧  - 06/12/7(木) 16:16 -

引用なし
パスワード
   ▼アイマール さん:
こんにちは。

>> エラー発生時において、ctl という変数の中には
>> どのコントロールが入っているのでしょうか。
>
>あるクエリを元に貼り付けたコントロールの種類は「テキストボックス」、「コンボボックス」、
>「チェックボックス」の3つのみです。
>したがって、ctlの変数には上の3つのコントロールが入っていると思いますが、如何でしょうか。

デバッグの仕方はご存知ですか?
エラーが出た状態でイミディエイトウィンドウ
(デフォルトの状態ですと ctrl + G を押すと起動されます)にて

? ctl.Name

と入力しEnterキーを押し、
どのコントロールでエラーが発生しているかを確実にしてみましょう。


当方も色々と試してみたのですが、
どうやらオプショングループの中にあるチェックボックスにおいては
OldValue や Value の値が取れないようですね。

【8875】Re:履歴について
質問  アイマール  - 06/12/7(木) 16:53 -

引用なし
パスワード
   ▼小僧 さん:
こんにちは。

Print ctl.Name で試した結果、以下の通りになりました。
エラーは、ほとんどテキストボックスからエラーが出ておりました。

姓、名など、エラーが出ていないテキストボックスと、緊急連絡先、住所、などエラーが
出ているテキストボックスがあるそうです。
ちなみにコンボボックスはエラーがありませんでした。

エラーが出ているテキストボックスを全て削除し、エラーが出てないテキストボックスと
コンボボックスだけ残して、編集してみると、フィールド名もきちんと表示され、うまく行きました。

いったい、どうなっているのでしょうか。。。。

【8877】Re:履歴について
発言  小僧  - 06/12/7(木) 17:50 -

引用なし
パスワード
   ▼アイマール さん:
こんにちは。

だんだんと原因は絞られてきた様な気がしませんでしょうか。
次にチェックするのはエラーが起こるテキストボックスと
エラーがおきないテキストボックスで何が違うのか調べてみましょう。

例として…

Option Compare Database
Option Explicit

Sub TextBoxのプロパティをチェック()
Const FName = "該当フォーム名"
Dim DB As DAO.Database
Dim RS As DAO.Recordset
Dim strSQL As String
Dim FLG As Boolean
Dim ctl As Access.Control
Dim i As Long

  Set DB = CurrentDb
  On Error Resume Next
    DoCmd.DeleteObject acTable, "EX_TableCheck"
  On Error GoTo 0
  
  DoCmd.OpenForm FName, acDesign
  FLG = True
  
  For Each ctl In Forms(FName).Controls
    If ctl.ControlType = acTextBox Then
      If FLG Then
        Call Create_Table(DB, ctl)
        FLG = False
      End If
      Set RS = DB.OpenRecordset("EX_TableCheck", dbOpenDynaset)
        RS.AddNew
          
        For i = 1 To RS.Fields.Count - 1
          On Error Resume Next
          RS(i).Value = ctl.Properties(Mid(RS(i).Name, 3))
          If Err.Number <> 0 Then
            RS(i).Value = "ERROR!!!"
          
          End If
          On Error GoTo 0
        Next
        RS.Update
        RS.Close
    End If
  
  Next
  DoCmd.Close acForm, FName
  Set RS = Nothing
  Set DB = Nothing
End Sub

Function Create_Table(DB As DAO.Database, objText As Access.TextBox)
Dim strSQL As String
Dim strField As String
Dim prp As Object

  For Each prp In objText.Properties
    strField = strField & ", F_" & prp.Name & " TEXT(50)"
  Next

  strSQL = "CREATE TABLE EX_TableCheck(" _
      & "SEQ Counter(1), " _
      & Mid(strField, 2) _
      & ");"

  DB.Execute strSQL, dbFailOnError

End Function


上記の様なコードを標準モジュールに記載し実行した後に
テーブル EX_TableCheck の値を見比べて見ると何か見つかるかもしれません。
(見つからないかも…しれません…。)

1078 / 2272 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
1078205
(SS)C-BOARD v3.8 is Free