[[20120328091213]] 『数字の表示位置が微妙にずれる。』(偽のマダラ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『数字の表示位置が微妙にずれる。』(偽のマダラ)

Excel 2000 or 2003 Os Xp

Sqlでデータの作成、更新をおこなっているのですが、数値の項目の表示位置が微妙にずれていて気持ち悪いです。

表示位置を右詰にしても解決できません。なぜこのようなことが起きるのかがわかりませ。

よろしくお願いします。

 ******データ*******

   A
1   1
2   1
3  1
4   1

 表示形式が違うのでは?
 (追記) 
 標準、数値が混在していませんか。 
(おも)

おも様へ、返信ありがとうございます。

標準と数値が混在しておりました。

原因は数値のところにSqlで更新をかけると、何故か標準に形式がなってしまうためです。対応策等はありますでしょうか?


 >Sqlでデータの作成、更新をおこなっているのですが
 SQLでクエリを行っているデータは、何ですか?
 データの提示や
 SQLというなら、VBAなんですか?
 だったら。、コードを提示して再現手順書を記述してください。

 ichinose


ichinose様へ、返信ありがとうございます。

以下にコードの抜粋を載せますので確認ください。エラーがでたらごめんなさい。

private sub abc ()

	dim lngUserCd as long
	dim dateDay as date
	dim strJikyuCd as string 
	dim strSQLNew as string 
        dim adoCon As New ADODB.Connection
        dim adoRs As New ADODB.Recordset

	   lngUserCd =1
           dateDay = "2012/03/29"
	   strJikyuCd = "0000000001"

            adoCon.Open "Driver={Microsoft Excel Driver (*.xls)};" & _
                        "DBQ=" & "C:\test\test.xls" & ";" & _
                        "ReadOnly=0"

            strSQL = "Select * From [Test$] Where コード=" & lngUserCd & _
                    " And 日付 = #" & dateDay & "#"

            Set adoRs = adoCon.Execute(strSQL)

            If Not adoRs.EOF Then

                strSQLNew = ""
                strSQLNew = "Update [Test$] "
                strSQLNew = strSQLNew & " Set A='" & strJikyuCd & "' "
                strSQLNew = strSQLNew & " ,支援フラグ=1" 
                strSQLNew = strSQLNew & " Where コード=" & lngUserCd
                strSQLNew = strSQLNew & " And 日付 = #" & dateDay & "#"

                adoCon.Execute strSQLNew

	   End If

end sub

***データシート*******

   A             日付         支援フラグ   コード
1  1111111111   2012/03/29                 1
2  2222222222   2012/03/30    1            1

テストというシートにフィールドを4つ作り(A、日付、支援フラグ、コード)
支援フラグの表示形式を数値にしておき、上記SQLで更新をすると支援フラグの表示形式が標準になってしまう。
1行目のデータを更新。

※ActiveX Data Objects 2.5 liblary 参照
(偽のマダラ)


 >以下にコードの抜粋を載せますので確認ください。エラーがでたらごめんなさい。 
 最初から、この投稿をしてくださいね。

 Sub abc()
    Dim lngUserCd As Long
    Dim dateDay As Date
    Dim strJikyuCd As String
    Dim strSQLNew As String
    Dim strSQL As String
    Dim adoCon As ADODB.Connection
    Dim adoRs As ADODB.Recordset
    Set adoCon = New ADODB.Connection
    Set adoRs = New ADODB.Recordset
    lngUserCd = 1
    dateDay = "2012/03/29"
    strJikyuCd = "0000000001"

    adoCon.Open "Driver={Microsoft Excel Driver (*.xls)};" & _
                        "DBQ=" & ThisWorkbook.Path & "\test.xls" & ";" & _
                        "ReadOnly=0"
    strSQL = "Select * From [Test$] Where コード=" & lngUserCd & _
             " And 日付 = #" & dateDay & "#"
    adoRs.Open strSQL, adoCon, adOpenDynamic, adLockOptimistic
    If Not adoRs.EOF Then
       adoRs![支援フラグ].Value = 1
       adoRs.Update
    End If
    adoRs.Close
    adoCon.Close
    Set adoCon = Nothing
    Set adoRs = Nothing
 End Sub

 試してみてください。書式は、上記では変わりませんでした。

 尚、初期設定が標準では駄目なんですか?

 ichinose


ichinose様、返信ありがとうございます。

以下に追加でコードを書きます。何度もすいません。

private sub abc ()

	dim lngUserCd as long
	dim dateDay as date
	dim strJikyuCd as string 
	dim strSQLNew as string 
        dim adoCon As New ADODB.Connection
        dim adoRs As New ADODB.Recordset

	   lngUserCd =1
           dateDay = "2012/03/29"
	   strJikyuCd = "0000000001"

 For i = 2 To 32

	    dateDay = Sheets("Testdata").Range("A" & i)
            adoCon.Open "Driver={Microsoft Excel Driver (*.xls)};" & _
                        "DBQ=" & "C:\test\test.xls" & ";" & _
                        "ReadOnly=0"

            strSQL = "Select * From [Test$] Where コード=" & lngUserCd & _
                    " And 日付 = #" & dateDay & "#"

            Set adoRs = adoCon.Execute(strSQL)

 	If Sheets("Testdata").Range("E" & i) <> "" Then

	    If Not adoRs.EOF Then

                strSQLNew = ""
                strSQLNew = "Update [Test$] "
                strSQLNew = strSQLNew & " Set A='" & strJikyuCd & "' "
                strSQLNew = strSQLNew & " ,支援フラグ=1" 
                strSQLNew = strSQLNew & " Where コード=" & lngUserCd
                strSQLNew = strSQLNew & " And 日付 = #" & dateDay & "#"

                adoCon.Execute strSQLNew

	  else
                strSQLNew = ""
                strSQLNew = "Insert Into [Test$] ( "
                strSQLNew = strSQLNew & " A "
                strSQLNew = strSQLNew & " ,コード "
                strSQLNew = strSQLNew & " ,日付 "
                strSQLNew = strSQLNew & " ,支援フラグ) "
                strSQLNew = strSQLNew & " Values ("
                strSQLNew = strSQLNew & " '" & strJikyuCd & "'"
                strSQLNew = strSQLNew & " ," & lngUserCd
                strSQLNew = strSQLNew & " ,#" & dateDay & "#"
                strSQLNew = strSQLNew & " ," & 1 & " )"

                adoCon.Execute strSQLNew

	   End If

	else

	    If Not adoRs.EOF Then

                strSQLNew = ""
                strSQLNew = "Update [Test$] "
                strSQLNew = strSQLNew & " Set A='' "
                strSQLNew = strSQLNew & " ,支援フラグ=null"
                strSQLNew = strSQLNew & " ,日付=null"
                strSQLNew = strSQLNew & " ,コード=null"
                strSQLNew = strSQLNew & " Where コード=" & lngUserCd
                strSQLNew = strSQLNew & " And 日付 = #" & dateDay & "#"

                adoCon.Execute strSQLNew

	   End if
	end if

            adoRs.Close
            adoCon.Close
	    set adors = nothing
	    set adoCon = nothing
next

end sub

***データシート*******

   A             日付         支援フラグ   コード
1  1111111111   2012/03/29                 1
2  2222222222   2012/03/30    1            1

**テストデータシート

      A (日付)   B(A)         C(コード)     D(支援フラグ)     E(出勤フラグ)
1 2012/03/01
2 2012/03/02
    ・
  ・
29 2012/03/29    1111111111    1             1                  1
    ・
31 2012/03/31

テストデータというシートを作り、そこのデータの内容をテストシートに書き込む。
テストシートになければ登録、あれば更新、テストシートにのみあるデータは更新で初期化して
います。

*再現手順***

@テストデータからデータを削除。
Aテストデータに新規にデータを登録。

すると、数値に設定していたものが標準になってしまう。

原因はわかりませんが、insert時に標準の項目を使用してしまいこれが原因でした。
一応、数値の項目は全て、数値に表示形式を設定しています。

>>尚、初期設定が標準では駄目なんですか? →CsvファイルをSqlで取込み、レコードセットを一括でシートに書き込んでいるのですが、数値を文字列として扱ってしまうため、
数値に表示形式を設定しています。

(偽のマダラ)


 まず、私が前回投稿したコードについてのフィードバックをしてください。
 提示したコードに関してのコメントがないので先へ進めません。

 >CsvファイルをSqlで取込み、レコードセットを一括でシートに書き込んでいるのです
 これも例題を示していただかないと再現ができません。
 schema.iniファイルを使い、各列の属性を定義すれば、出来そうですが、
 これは、後にしましょう。

 提示されたコードもSQLで全て処理しようとしていますが、
 私が投稿したようなRecordSetオブジェクトのプロパティを介しての
 更新や登録で行ってみては?

 ichinose


ichinose様へ、返信ありがとうございます。

Recordsetオブジェクトのプロパティを使って最初はやっていたのですが、原因不明のエラーがでたため、SQLに変えました。

最初はデータの更新ができても、何かの時におかしくなると特定の行で毎回エラーになります。これをSQL文にかえたらエラーがでなくなりましたので現在、SQLを使用しております。

エラーはたしか、「日付の形式/型が正しくありません」のようなメッセージでした。

日付以外の項目を更新しているにもかかわらず上記のエラーがでてしまいました。(偽のマダラ)


 >日付以外の項目を更新しているにもかかわらず上記のエラーがでてしまいました
 本当は、この時のデータとかコードとエラー箇所等を含んだ再現手順を見てみたいのですけどねえ・・・。
 私は、仕事では、9割がたADOを使っています。Excelに繋ぐのは、読み込み目的でしか
 使用した経験はありませんので非常に興味があるんですが・・・・。

 目的がある列の数字の不ぞろいの是正なら、前回の投稿で後回しにしていた

 >>尚、初期設定が標準では駄目なんですか? →CsvファイルをSqlで取込み、レコードセットを一括でシートに書き込んでいるのですが、数値を文字列として扱ってしまう

 ここの読み込みを schema.iniファイルを使って、列のデータ型を規定するのはいかがですか?
 そうすれば、ブックの書式は、標準でよいはずですから・・・。

 これもCSVのデータ例などの提示が必要ですが・・・・。

 もっとも私には、
 >数値を文字列として扱ってしまう
 が再現できませんでしたが・・・・。

 CSVのデータ例を記述できますか?

 ichinose


ichinose様へ、返信ありがとうございます。

以下にコードとCSVのデータ例を書きます。

あと、schema.iniは使用したことがないのでアドバイス頂けると助かります。

よろしくお願いします。

Public Function test_Data(intCellno As Integer, strSheetNm As String, strHaniNm As String) As Boolean

    Dim adoCon As New ADODB.Connection
    Dim adoRs As ADODB.Recordset
    Dim strSQL As String
    Dim strFullPath As String

    Dim strDataPath As String

    Dim lngLastRow As Long

    test_Data= False

    strFullPath = Range(strHaniNm)

    adoCon.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
                "DBQ=" & Left(strFullPath, InStrRev(strFullPath, "\")) & ";" & _
                "ReadOnly=1"

    strSQL = ""
    strSQL = "Select * "
    strSQL = strSQL & " From " & "[" & strSheetNm & "]"
    strSQL = strSQL & " Where Sien_Flg > 0 " & " Order by Sien_Flg"  

    Set adoRs = adoCon.Execute(strSQL)

    If adoRs.EOF Then
        MsgBox "CSVのデータがありません。"
        Exit Function
    End If

    Sheets("testdata").Select
    ActiveSheet.Range("J2:K65536").Select
    Selection.NumberFormatLocal = "0_ " 

    ActiveSheet.Range("A2:IV65536").ClearContents

    ActiveSheet.Range("A" & ActiveSheet.Cells(65536, 1).End(xlUp).Row + 1).CopyFromRecordset adoRs

    adoRs.close  
    adoCon.Close

    Set adoRs = Nothing
    Set adoCon = Nothing

    test_Data= True

End Function

*** CSV ***********

"ID","ID_Name","Sien_Flg","Bunrui_ID","Day","time1","time2","Shukin_Flg"
1,"太郎",1,2,2012/02/01 0:00:00,"9:00","17:00",1

こんな感じでやっているのですが、数値列にしないと、Sien_Flg等の項目が '1のように数字の前に ' がついてしまいコメント扱いになってしまいます。
(偽のマダラ)


 >数値列にしないと、Sien_Flg等の項目が '1のように数字の前に ' がついてしまいコメント扱いになってしまいます。 
 私の環境では、提示されたコードでSien_Flgも数字で表示されましたが・・・。
 Providerが違うのかなあ。
 取りあえず、schema.iniで試してみてください。

 以下のコードを新規ブックにて試してください。

 標準モジュール(Module1)にサンプルCSV作成コード

 '=============================================================
 Sub mk_sample_csv()
    Dim flnm As String
    Dim fno As Long
    fno = FreeFile()
    Open ThisWorkbook.path & "\test.csv" For Output As fno
    Print #fno, """ID"",""ID_Name"",""Sien_Flg"",""Bunrui_ID"",""Day"",""time1"",""time2"",""Shukin_Flg"""
    Print #fno, "1,""太郎"",1,2,2012/02/01 0:00:00,""9:00"",""17:00"",1"
    Print #fno, "2,""次郎"",2,2,2012/02/5 0:00:00,""9:30"",""17:00"",2"
    Close #fno

 End Sub

 別の標準モジュール(Module2)に
 Ado及び、schema.ini関連プロシジャー群

 '=====================================================================
 Option Explicit
 Private cn As Object
 '=====================================================================
 Function open_ado_text(path As String) As Long
    On Error Resume Next
    Dim link_opt As String
    Set cn = CreateObject("adodb.connection")

    link_opt = "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
                 "DBQ=" & path & ";" & "ReadOnly=0"

    cn.Open link_opt
    open_ado_text = Err.Number
    On Error GoTo 0
 End Function
 '=====================================================================
 Sub close_ado()
    On Error Resume Next
    cn.Close
    On Error GoTo 0
 End Sub
 '=====================================================================
 Function exec_sql(sql_str, rs As Object) As Long
    On Error Resume Next
    Set rs = cn.Execute(sql_str)
    exec_sql = Err.Number
    If Err.Number <> 0 Then MsgBox Err.Description
    On Error GoTo 0
 End Function
 '=====================================================================
 Function mk_schema_ini(path As String, dat() As String) As Long
    On Error GoTo err_mk_schema_ini
    Dim fno As Long
    Dim didx As Long
    mk_schema_ini = 0
    fno = FreeFile()
    Open path & "\schema.ini" For Output As #fno
    For didx = LBound(dat()) To UBound(dat())
       Print #fno, dat(didx)
       Next
    Close #fno
 ret_mk_schema_ini:
    On Error GoTo 0
    Exit Function
 err_mk_schema_ini:
    MsgBox Err.Description
    mk_schema_ini = Err.Number
    Resume ret_mk_schema_ini
 End Function
 '=====================================================================
 Function del_schema_ini(path As String)
    On Error Resume Next
    Kill path & "\schema.ini"
    On Error GoTo 0
 End Function

 別の標準モジュール(Module3)にTest.Csv読み込みプロシジャー

 '=====================================================================
 Sub main()
    Dim ret As Long
    Dim dat(1 To 12) As String
    Dim rs As Object
    Dim ans As Variant
    dat(1) = "[test.csv]"
    dat(2) = "ColNameHeader = true"
    dat(3) = "CharacterSet = oem"
    dat(4) = "Format = CSVDelimited"
    dat(5) = "Col1=id double"
    dat(6) = "Col2=id_name char width 255"
    dat(7) = "Col3=Sien_Flg double"
    dat(8) = "Col4=Bunrui_ID double"
    dat(9) = "Col5=Day Date"
    dat(10) = "Col6=time1 char width 255"
    dat(11) = "Col7=time2 char width 255"
    dat(12) = "Col8=Shukin_Flg double"
    Call mk_schema_ini(ThisWorkbook.path, dat())
    ret = open_ado_text(ThisWorkbook.path)
    If ret = 0 Then
       ret = exec_sql("select * from [test.csv]  Where Sien_Flg > 0 Order by Sien_Flg", rs)
       If ret = 0 Then
          Range("a1").CopyFromRecordset rs
          rs.Close
       Else
          MsgBox Error(ret)
          End If
       close_ado
       End If
    Call del_schema_ini(ThisWorkbook.path)
 End Sub

操作手順

 まず、上記マクロのあるブックを適当な名前で保存してください
 ↑これを必ず、行うこと。

 次に「mk_sample_csv」を実行して、サンプルCSVファイルを作成してください。
 作成したら、メモ帳などで提示されたcsvファイルと内容が同じである事を確認してください。

 最後に「main」を実行して、シートに読み込まれたデータを確認してください。
 今まで文字列だったデータは、数値になっていませんか?

 試してみてください。

 ichinose


ichinose様へ、返信ありがとうございます。

こんなやり方があるのですね。勉強になります。

もう一度調べてみたら、文字列になる原因がCSVコピー時ではなく、シートにコピーした後にSQLで項目を更新しておりましてその時になるようなことがわかりました。

申し訳ありません。

* CSV ***********

"ID","ID_Name","Sien_Flg","Bunrui_ID","Day","time1","time2","Shukin_Flg"
1,"太郎",1,2,2012/02/01 0:00:00,"9:00","17:00",1

** dataシート******

  A     B          C          D                    E      F       G           H        
1 ID  ID_Name  Sien_Flg  Bunrui_ID  Day          time1  time2   Shukin_Flg  add_item
2 1    太郎    1          2         2012/02/01   9:00   17:00      1        ★ここを更新      

CSVをシートにコピーした後、CSVにはない項目を更新しています。
Shukin_Flgが1の時、add_itemに1をSQLでupdateしているのですが、これをすると文字列になってしまいます。'1のようになる。

再現できればいいのですが・・・。

dataシートを検索してShukin_Flgが1のものの主キー(id、day)を使用して、update文を発行しています。(Recordsetのプロパティではありません。)

CSVにない項目をschema.ini等で設定することは可能でしょうか?
やはり、対象セルの書式を設定する方法しかないのでしょうか?
(偽のマダラ)


 やっと、現象確認しました。

 なるほど・・・、add_itemという列(Field)の更新で確かに'1となりました。
 時間が出来たら、再現手順を投稿tします。

 ADOXで何とかなるか探って見ますが、
 応急には、このadd_itemと言う列の書式を通貨(\は、なし にする) にしてみては?
 いかがですか?
 そうすれば、数字のバラつきはなくなりますよね!!

 ADOXでのField属性操作に関しては、夕方(深夜)まで待ってください。
 私もExcelでは、初めてなので・・・。
 因みに SQL ALTERでは、駄目でした

 ichinose


ichinose様へ、返信ありがとうございます。

解決策がみつかれば、とても助かります。(偽のマダラ)


 ADOXでも駄目でした。
 Excelでの扱いは、難しいですね!!

 数値項目は、既定値として、0を入れる と言う方針では、

 新規ブックにて、

 まず、ファイルの規定

 test.csv  読み込むCSVファイル
 test.xls  csvファイルを読み込むExcelブック(対象シート名 testdata)
 macro.xls   上記二つをマクロで操作するVBAコードを含んだブック

 macro.xlsの標準モジュールにて、

 '====================================================================
 Sub mk_sample_file()
    Dim flnm As String
    Dim fno As Long
    Dim testdata  As Worksheet
    fno = FreeFile()
    Open ThisWorkbook.path & "\test.csv" For Output As fno
    Print #fno, """ID"",""ID_Name"",""Sien_Flg"",""Bunrui_ID"",""Day"",""time1"",""time2"",""Shukin_Flg"""
    Print #fno, "1,""太郎"",1,2,2012/02/01 0:00:00,""9:00"",""17:00"",1"
    Print #fno, "2,""次郎"",2,2,2012/02/5 0:00:00,""9:30"",""17:00"",2"
    Close #fno
    Set testdata = Workbooks.Add.Worksheets(1)
    With testdata
       .name = "testdata"
       .Range("a1:i1").Value = Array("ID", "ID_Name", "Sien_Flg", "Bunrui_ID", "Day", "time1", "time2", "Shukin_Flg", "add_item")
       .Range("e:e").NumberFormatLocal = "yyyy/m/d"
       .Parent.SaveAs ThisWorkbook.path & "\test.xls"
       .Parent.Close False
    End With
    Set testdata = Nothing
 End Sub

 必ず、保存した後に上記のmk_sample_file実行し、サンプルファイルを作成してください
 作成ファイルは、 test.csv test.xlsです。

 別の標準モジュールに
 Ado及び、schema.ini関連プロシジャー群

 Option Explicit
 Private cn As Object
 Function open_ado_excel(path As String) As Long
    On Error Resume Next
    Dim link_opt As String
    Set cn = CreateObject("adodb.connection")

    link_opt = "Driver={Microsoft Excel Driver (*.xls)};" & _
                        "DBQ=" & path & ";" & _
                        "ReadOnly=0" & ";FirstRowHasNames=1"

    cn.Open link_opt
    open_ado_excel = Err.Number
    On Error GoTo 0
 End Function
 Function open_ado_text(path As String) As Long
    On Error Resume Next
    Dim link_opt As String
    Set cn = CreateObject("adodb.connection")

    link_opt = "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
                 "DBQ=" & path & ";" & "ReadOnly=0"

    cn.Open link_opt
    open_ado_text = Err.Number
    On Error GoTo 0
 End Function
 Sub close_ado()
    On Error Resume Next
    cn.Close
    On Error GoTo 0
 End Sub
 Function exec_sql(sql_str, Optional rs As Object, Optional opn As Boolean = False) As Long
    On Error Resume Next
    If TypeName(rs) = "Recordset" Then
       If opn Then
          rs.Open sql_str, cn, adOpenStatic, adLockOptimistic
       Else
          Set rs = cn.Execute(sql_str)
       End If
    Else
       cn.Execute sql_str
    End If
    exec_sql = Err.Number
    If Err.Number <> 0 Then MsgBox Err.Description
    On Error GoTo 0
 End Function
 Function mk_schema_ini(path As String, dat() As String) As Long
    On Error GoTo err_mk_schema_ini
    Dim fno As Long
    Dim didx As Long
    mk_schema_ini = 0
    fno = FreeFile()
    Open path & "\schema.ini" For Output As #fno
    For didx = LBound(dat()) To UBound(dat())
       Print #fno, dat(didx)
       Next
    Close #fno
 ret_mk_schema_ini:
    On Error GoTo 0
    Exit Function
 err_mk_schema_ini:
    MsgBox Err.Description
    mk_schema_ini = Err.Number
    Resume ret_mk_schema_ini
 End Function
 Function del_schema_ini(path As String)
    On Error Resume Next
    Kill path & "\schema.ini"
    On Error GoTo 0
 End Function

 別の標準モジュールに
 Sub CSVの読み込み()
    Dim ret As Long
    Dim dat(1 To 12) As String
    Dim rs As Object
    Dim ans As Variant
    Dim bk As Workbook
    Dim rng As Range
    dat(1) = "[test.csv]"
    dat(2) = "ColNameHeader = true"
    dat(3) = "CharacterSet = oem"
    dat(4) = "Format = CSVDelimited"
    dat(5) = "Col1=id double"
    dat(6) = "Col2=id_name char width 255"
    dat(7) = "Col3=Sien_Flg double"
    dat(8) = "Col4=Bunrui_ID double"
    dat(9) = "Col5=Day Date"
    dat(10) = "Col6=time1 char width 255"
    dat(11) = "Col7=time2 char width 255"
    dat(12) = "Col8=Shukin_Flg double"
    Call mk_schema_ini(ThisWorkbook.path, dat())
    Set bk = Workbooks.Open(ThisWorkbook.path & "\test.xls")
    ret = open_ado_text(ThisWorkbook.path)
    If ret = 0 Then
       Set rs = CreateObject("adodb.recordset")
       ret = exec_sql("select * from [test.csv]  Where Sien_Flg > 0 Order by Sien_Flg", rs)
       If ret = 0 Then
          bk.Worksheets("testdata").Range("a2").CopyFromRecordset rs
          With bk.Worksheets("testdata")
             Set rng = .Range("h2", .Cells(.Rows.Count, "h").End(xlUp))
             rng.Offset(0, 1).Value = 0 'add_itemの列のデータのある行まで0を規定値
          End With
          rs.Close
          bk.Close True
       Else
          MsgBox Error(ret)
          End If
       close_ado
       End If
    Call del_schema_ini(ThisWorkbook.path)
 End Sub
 Sub Excelブック更新()
    Dim ret As Long
    ret = open_ado_excel(ThisWorkbook.path & "\test.xls")
    If ret = 0 Then
       'ret = exec_sql("Update [testdata$] Set add_item = null")
       ret = exec_sql("Update [testdata$] Set add_item = 1 Where Shukin_Flg = 1")
       close_ado
       End If
 End Sub
 Sub Excelブックにデータ追加()
    Dim ret As Long
    Dim dat(1 To 12) As String
    Dim rs As Object
    ret = open_ado_excel(ThisWorkbook.path & "\test.xls")
    If ret = 0 Then
       ret = exec_sql("insert into [testdata$] (ID,ID_Name,Sien_Flg,Bunrui_ID,Day,time1,time2,Shukin_Flg,add_item) values(" & _
                       "3,'三郎',3,2,#2012/3/15 00:00:00#,'9:30','17:00',1,1)")
       If ret = 0 Then
       Else
          MsgBox Error(ret)
          End If
       close_ado
       End If
 End Sub

 以上です。
 CSVの読み込み、Excelブック更新、Excelブックにデータ追加の順で実行してみてください。正常にadd_itemの列のデータが正しく入力されていると思います。

 ポイントは、数値列は、数字が入っていないと列の属性がわからないということです。

 ichinose


ichinose様へ、返信ありがとうございます。

数値列は値が入ってないと、更新したら文字列になってしまうのですね!!

できれば0ではなく、空白でなんとかしたかったのですが残念です。

0をいれるかあらかじめ表示形式を数値にして対応するのか検討したいと思います。

ありがとうございました。(偽のマダラ)


 >あらかじめ表示形式を数値にして対応する
 これね、Add_Itemと言う列を数値形式にしても列のどこにも数値が入っていない状態で
 更新・追加を行うと 例の '1 と言う形式で設定されてしまいますよ!!
 どこかに数値が入っていれば、位置がずれても数値として扱われます。

 試しに前回投稿のmk_sample_fileを実行後、
 test.xlsを開いて、Add_Item列の書式を数値に変更、保存してから、
 CSVの読み込み 以降のプロシジャーを実行して見てください
 尚、CSVの読み込み での以下のコードはコメントにして試してください。

          >With bk.Worksheets("testdata")
          >   Set rng = .Range("h2", .Cells(.Rows.Count, "h").End(xlUp))
          >   rng.Offset(0, 1).Value = 0 'add_itemの列のデータのある行まで0を規定値
          >End With

 >できれば0ではなく、空白でなんとかしたかった
 0に関しては、0値の表示に関して、オプションで指定できますが、これで対処できませんか?

 ichinose 


ichinose様へ、返信ありがとうございます。

たしかに数値に変えてからやっても文字列になりますね。

ただ、一度SQLで更新し、文字列にした後、データを消し、表示形式を数値にしてから1を入力し、その後セルのデータを空白にし、エクセルを保存するとSQLで更新しても数値になることがわかりました。(一度やれば2度目からはやらなくてよい。)

Sql更新→文字列数値を空白にする→表示形式→数値→1を入力→空白にする→保存→SQLでadd_item更新

原因がわからないままプログラム作成をしていたら、いつのまにか文字列にならなくなっていたので根本の原因がわかってよかったです。

@新規にエクセルを作成し、SQLで数値データを更新する時は空白セルに0をいれる。
A雛形のxlsをコピーしてからデータのエクセルを作成する場合は、上記の方法で対応する。(その他の場合)

以上の2通りのパターンを設計段階で考えて使いわけていきたいと思います。

こちらではAの方法でやっておりますので、とりあえずこのままでいきたいと思います。更新毎にセルを数値列にしないといけないですが・・・。

@の方法は最終手段としておきます。最初の段階でこちらの方法をとっていれば問題はなかったのですが残念です。

ichinose様とても勉強になりました。ありがとうございました。(偽のマダラ)


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.