nikorasu277
@nikorasu277 (keiji mori)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

ExcelVBAを使用し、accessのテーブルにレコード追加

ExcelVBAを使用し、accessのテーブルを更新したい。
Excelのボタンをクリックすることで、更新できる仕様にしたいです。

INSERT INTO構文はいくらでもネットに出てくるのですが、Excel側の様式が決まっており、「各所のセルから様々な型」でテーブルに追加しなければなりません。

初心者ですが、力をお貸しいただきたいところです。
できれば急ぎで解決したいところなのです。。

何卒、ご教示お願いいたします。

発生している問題・エラー

image.png

実行時エラー'エラー13':
型が一致しません。

以下、コードです。

ExcelVBA

Sub ボタン3_Click()

    Dim dbPath As String
    dbPath = "C:\Users\hayab\Desktop\てすと!!\テスト.accdb"

    ' データベース接続を開始
    Dim conn As Object
    Set conn = CreateObject("ADODB.Connection")
    conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath

    ' SQLクエリを作成
    Dim strSQL As String
  strSQL = "INSERT INTO T_テーブル (文字型1, 文字型2, 数値型, カレンダー, ボックス) VALUES (" & _
             "'" & Sheets("Sheet1").Cells(2, 5).Value & "', " & _
             "'" & Sheets("Sheet1").Cells(2, 6).Value & "', " & _
             Replace(Sheets("Sheet1").Cells(2, 8).Value, ",", "") & ", " & _
             "#" & Format(CDate(Sheets("Sheet1").Cells(10, 2).Value), "yyyy/mm/dd") & "#, " & _
             "'" & IIf(Sheets("Sheet1").Shapes("チェック 4").ControlFormat.Value = xlOn, "有", "無") & "')"



    ' SQLクエリを実行
    conn.Execute strSQL

    ' データベース接続をクローズ
    conn.Close
    Set conn = Nothing
End Sub

以下、accessの「T_テーブル」のフィールドです。

image.png

以下、Excelsheet1のスクショです。

image.png

Microsoftのドキュメントを確認し、試してみましたが、いずれもコード内に文字型の文字を記載して、accessのテーブルに追加する基礎的なものしかなく、「Cells、Range、カレンダー(2023/10/1)」などを指定してのテーブル追加の記事がなく、困っています。。

何卒お力をお貸しください。
よろしくお願いいたします。

0

2Answer

@gx3n-inue さん、お陰様で時間はかかりましたが、一つ一つ確認した結果、期待した結果が得られました。以下、コードです。感謝いたします。ありがとう。

Sub ボタン3_Click()

    Dim dbPath As String
    dbPath = "C:\Users\hayab\Desktop\てすと!!\テスト.accdb"

    ' データベース接続を開始
    Dim conn As Object
    Set conn = CreateObject("ADODB.Connection")
    conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath

    ' SQLクエリを作成
    Dim strSQL As String
    
''''''SQLではRange(配列型)は対応できないため、各セルから抽出する''''''''''''
    Dim レンジ系 As String
    Dim cell As Range
 
 
 ' レンジ系の各セル値を取得し、カンマで区切って文字列に結合
For Each cell In Range("B10:B12")
    レンジ系 = レンジ系 & cell.Value & ","
Next cell

' 最後のカンマを削除
If Len(レンジ系) > 0 Then
    レンジ系 = Left(レンジ系, Len(レンジ系) - 1)
End If
      
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  
  
'''''日付型は、事前にフォーマットに変換する必要がある。'''''''''''''''''''''''''''''''''
Dim 日付型 As Date
日付型 = Range("B7").Value
  
  
' 日付を yyyy/mm/dd 形式の文字列に変換
Dim 日付文字列 As String
日付文字列 = Format(日付型, "yyyy/mm/dd")
  
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
''チェックボックスがチェックされているか否かによって、「有」「無」とレコードに記載する''

Dim チェックボックス As String
If Sheets("Sheet1").Shapes("チェック 4").ControlFormat.Value = xlOn Then  'フォームコントロールの「チェック 4」というcheckbox
    チェックボックス = "有"
Else
    チェックボックス = "無"
End If

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''    
    文字型1 = Range("B5").Value
    文字型2 = Range("B6").Value
    数値型 = Range("B8").Value
    
  
  strSQL = "INSERT INTO T_テーブル (文字型1,文字型2,数値型,レンジ系,日付型,チェックボックス) " & _
            "Values('" & 文字型1 & "','" & 文字型2 & "'," & 数値型 & ",'" & レンジ系 & "','" & 日付文字列 & "','" & チェックボックス & "');"


    ' SQLクエリを実行
    conn.Execute strSQL

    ' データベース接続をクローズ
    conn.Close
    Set conn = Nothing
End Sub




image.png

2Like

Comments

  1. 解決したのであれば、クローズにするといいですよ。

実際に私の手元でも確かめれば、エラーの箇所を絞り込めるかもしれませんが、
ちょっと手元に動作環境がないので、エラーの箇所を絞り込む手法だけ書きます。

エラーは、

    ' SQLクエリを実行
    conn.Execute strSQL

で発生しているかと思いますが、

その前に、

strSQL = "INSERT INTO T_テーブル (文字型1, 文字型2, 数値型, カレンダー, ボックス) VALUES (" & _
             "'" & Sheets("Sheet1").Cells(2, 5).Value & "', " & _
             "'" & Sheets("Sheet1").Cells(2, 6).Value & "', " & _
             Replace(Sheets("Sheet1").Cells(2, 8).Value, ",", "") & ", " & _
             "#" & Format(CDate(Sheets("Sheet1").Cells(10, 2).Value), "yyyy/mm/dd") & "#, " & _
             "'" & IIf(Sheets("Sheet1").Shapes("チェック 4").ControlFormat.Value = xlOn, "有", "無") & "')"

でセットされている値で型の不一致があると思いますので、
どのセルから取り出した値がエラーになっているのか、判別した方が良いですね。

あと、、SQL文も、
どのようなフォーマット/型で与えればエラーにならないか、

INSERT INTO T_テーブル (文字型1, 文字型2, 数値型, カレンダー, ボックス) VALUES ('aaa', 'bbb', 123, #2023/10/15#, '有')

などのようにVALUESを定数で与えて、
格納先のDB/TABLEに合わせて、エラーにならずにINSERT文が実行される書式を事前に把握しておいた方が良いです。

また、各セルから取り出す値についても、

' (変数の宣言はお任せします)
' ...
a = Sheets("Sheet1").Cells(2, 5).Value 
b = Sheets("Sheet1").Cells(2, 6).Value
c = Replace(Sheets("Sheet1").Cells(2, 8).Value, ",", "")
d = Format(CDate(Sheets("Sheet1").Cells(10, 2).Value), "yyyy/mm/dd") 

のように、VBA側でいったん適当な変数に格納しておいて、
ウォッチ式で、格納された値を調べ、

必要に応じて、イミディエイトウインドウ上で、
VarType関数を使って目的の型でVBA側に読み込めているか調べてみてはいかがでしょうか?

もしくは、

strSQL = "INSERT INTO T_テーブル (文字型1, 文字型2, 数値型, カレンダー, ボックス) VALUES (" & _
             "'" & Sheets("Sheet1").Cells(2, 5).Value & "', " & _
             "''テスト用文字列 '", " & _
             "999", " & _
             "#2023/10/15#, " & _
             "'有") & "')"

' 型はパッと見で書いてますので、間違ってたらご自身で修正をお願いします。

などのように、いきなり4つのセルの値を代入するのではなく、
特定のセル以外は定数で代入してエラーが出るかどうか調べていく、
(この特定のセルを、順番に変えていく)

などの方法で、エラーの型の不一致が発生している箇所を絞り込んでいくという手もあると思います。

いずれにせよ、、SQLの実行時にエラーが発生するのを避けるために、

SQL文の実行前に、
入力値の型や、受け取った値が想定の範囲内かどうかを調べるなどの事前チェックの処理も、
堅牢なプログラムを作成するには考慮しておいた方が良いです。

事前の入力チェックの処理を用意しておくと、
誤った値がセットされているセル番地をユーザーに知らせる、なども機能も用意できるようになります。

1Like

Comments

  1. @nikorasu277

    Questioner

    @gx3n-inue さん、ご丁寧にありがとうございます。はまりにはまってコーディングが嫌いになりそうです(泣)
    1 おっしゃる通り、どの型がダメなのか、どこフォーマットであれば大丈夫なのか確認いたします。
    2 1つずつ代入するなどして、1つずつ検証してみたいと思います。

    1つずつ検証してみたいと思います。我に返れたきがします(泣)ありがとうございます。また、進展がありましたらこちらに記載いたします!

Your answer might help someone💌