tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re: vb6でaccessのデータ型が長いテキストが読み込めない
投稿日: 2024/02/05(Mon) 11:00
投稿者魔界の仮面弁士
なかなか厄介な問題ですね。


> accessのデータ型が長いテキストの項目(項目名「LongText」)が読み込めません。

エラーが発生した行に含まれている文字の長さは何文字ですか?
該当フィールドの文字列内に非可読文字――たとえば ChrW(0) など――が混入していませんか?

特定の文字が原因で誤動作を引き起こした経験があるので、
もしも VB6 では発生するが、Access VBA 側であれば発生しないのであれば、
VBA にてその中身を確認してみてください。

Public Function DumpText(ByVal Value As Variant) As String
    Dim S As String: S = ""
    Dim B() As Byte: B = "" & Value
    Dim P As Long
    For P = LBound(B) To UBound(B)
        S = S & Right$("00" & Hex(B(P)), 2)
    Next
    DumpText = S
End Function


なお当方では、とあるデータベースへの ODBC リンクテーブルに対して、
vbNullString な文字列を読み書きしたときにエラーになる事象を経験したことがあります。
それもトラップできる実行時エラーではなく、いわゆる一般保護違反でクラッシュする事象です。

この時は ODBC Driver のバグであったことが後に判明したのですが、
環境側の不具合が修正されるまでの間は、対症療法的に
 ''' 修正前
 'If IsNull(rs.Fields(0).Value) Then
 ' s0 = ""
 'Else
 ' s0 = CStr(rs.Fields(0).Value)
 'End If
 'rs.Fields(1).Value = s1
 
 ''' 修正後
 s0 = "" & rs.Fields(0).Value
 rs.Fields(1).Value = "" & s1
のようにして対応していました。
空文字列と連結することで、 Null や vbNullString を "" に置き換えるという回避策です。
今回の障害と関係するかは分かりませんが、一度試してみてはいかがでしょう。


> 項目名「LongText」には改行が含まれることもありますが、改行が含まれないデータでも読み込めません。

今回の事象を抜きにしても、その列名はあまり良くないですね。
LongText は予約語なので、フィールド名に使うことは避けた方が無難です。

予約語を SQL 中で使う場合、[〜] などで囲むなどのエスケープ処理が必要になるなど、
使い勝手が悪いですし、誤動作の要因にもなりえるため、別の名前の方が安全です。
(そのほか、No とか Name とか Date といった列名もトラブルの元です)

予約語の一覧はこちら。
https://learn.microsoft.com/ja-jp/office/troubleshoot/access/reserved-words?WT.mc_id=DT-MVP-8907


> If Not IsNull(TestTable00![LongText]) Then  'step1
それは省略表記ですよね。列の値ではなく列そのものを渡していますので、データ型を確認すると、
 Debug.Print TypeName(TestTable00![LongText])
は、"String" や "Null" などにはならないはずです。

COM オブジェクトに対する暗黙の自動型変換はパフォーマンス劣化の要因にもなりますので、面倒がらずに
 If Not IsNull(TestTable00![LongText].Value) Then
 If Not IsNull(TestTable00("LongText").Value) Then
 If Not IsNull(TestTable00.Fields("LongText").Value) Then
 If Not IsNull(TestTable00.Fields.Item("LongText").Value) Then
 If Not IsNull(TestTable00.Collect("LongText")) Then
などと記述することが望ましいです。
これらの表記であれば、取得されるのはフィールドではなくフィールド値となります。


> STest = TestTable00![LongText]            'step2
これも本来は、
 STest = TestTable00![LongText].Value
 STest = TestTable00.Fields("LongText").Value
 STest = TestTable00.Collect("LongText")
ですね。CStr を併用するかどうかはお好みで。


> まず普通に実行すると「実行時エラー5 プロシージャの呼び出し、または引数が不正です。」となります。
> エラーになっている箇所は「step2」で
> 「データのチェックができません。nullの使い方が不正です」となります。
コンパイルエラーではなく実行時エラーということは分かりましたが、
質問文にある上記 2 つのエラーメッセージが一貫していないようです。
メッセージの異なる両者の違いはなんでしょうか。
「普通に実行する」以外の実行手段として、具体的にどのように実行したのでしょうか?

また、"データのチェックができません。" というエラーメッセージは聞いたことがありませんが、
ひとまず、VBA エラー 94「Null の使い方が不正です。」では無いという認識で良いでしょうか。(Null ではなく null 表記ですし)
正確性を期すため、Err.Description の内容だけでなく、Err.Number と Err.Source も教えてください。


> 次はシングルステップで進み「step1」のTestTable00![LongText]部分にカーソルをあてるときちんと登録されている内容が表示されますが、
> 一度カーソルを別のところにもっていってからまたカーソルをあてると、なぜかNullと表示されてしまいます。
デバッグ実行ではなく、コンパイル実行した場合にも、同じ個所でエラーになりますか?

残念ながら VB6 開発環境は、Windows 11 での動作が保証されていません。
サポートされているのはランタイムのみであり、開発環境ではありません。

もしも EXE から実行した場合はエラー箇所が変わる(あるいはエラーにならない)場合は、
コンパイルオプションを、(標準の)ネイティブコードではなく、P-Codeに変更してみてください。
そのうえで P-Code の時だけ発生するようであれば、デバッガの不具合という可能性もありそうです。


過去ログ No15594 などでも触れられていますが、VB6.0 で開発するのであれば、
開発機には XP まで、せいぜい Vista までの環境、それも 32bit版を用意しておいた方が無難です。
※動作検証用の端末とは別に用意する。

参考までに下記も読んでみてください。とはいえ OS の修正プログラムなどで解消されることもあるので、
当時発生していたエラーが、いつの間にか発生しなくなっていた…という事象を自分は何度か経験しています。
https://hanatyan.sakura.ne.jp/patio/read.cgi?no=272


あとは、Recordset の CursorLocation を変更することで改善するかどうかを調べてみるとか。
adUseServer なら adUseClient に。adUseClient なら adUseServer にして動作を確認するということです。

現在の設定を確認しておきたいので、TestTable00.Open 後に下記を実行してみてください。

Debug.Print "CursorLocation="; TestTable00.CursorLocation
Debug.Print "    CursorType="; TestTable00.CursorType
Debug.Print "      LockType="; TestTable00.LockType


> そうすると「step2」ではなく「step3」に進むのでエラーはでません。
> ブレイクポイントを置かずに実行すると、「step1」でnullと判断されずに「step2」に進むのですが、
> 「step2」に来た時点でなぜかTestTable00![LongText]がnullになってしまっていてエラーになるようです。
ウォッチ ペインなどに、何らかの副作用を含む式が入っていた、ということはないでしょうか。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。