VB6アプリケーションを使用していますが、Unicode文字を保存しようとすると、MsSQLデータベースに正しく保存されません。SSMSで直接挿入ステートメントを実行すると、挿入は正しく実行されます。
Exec sp_Insert_item 1, 101, N'Ħass'
接続文字列のドライバーとしてSQLOLEDBを使用しており、列はNVarcharとして設定されています
誰かがこの問題を解決する方法を知っていますか?
ありがとう、アラン
VB6アプリケーションを使用していますが、Unicode文字を保存しようとすると、MsSQLデータベースに正しく保存されません。SSMSで直接挿入ステートメントを実行すると、挿入は正しく実行されます。
Exec sp_Insert_item 1, 101, N'Ħass'
接続文字列のドライバーとしてSQLOLEDBを使用しており、列はNVarcharとして設定されています
誰かがこの問題を解決する方法を知っていますか?
ありがとう、アラン
あなたの問題は、利用可能なほとんどのコントロールで遭遇する VB6 ソース コード文字列リテラル内の同じ ANSI のみの問題に関連していると思います。
君の:
CreateRecordset.Open "Exec sp_Insert_item 1, 101, N'Ħass'", conn, adOpenForwardOnly
実際には:
CreateRecordset.Open "Exec sp_Insert_item 1, 101, N'Hass'", conn, adOpenForwardOnly
...そこに貼り付けた後。
これはよくあることで、EscerLite
これに対処するために呼び出すクラスをよく使用します。もちろん、それは実行時に動作しますが、悲しいことに、コード内の String リテラル内で ChrW$() 呼び出しを連結するという代替手段よりも優れていることがよくあります。
私は通常、.CLS ファイルを編集してAttribute VB_PredeclaredId = True
、事前に宣言されたグローバルなインスタンスを作成します (VB6 の .FRM モジュールと同じように、モジュール名の名前が付けられた「フリー」フォーム インスタンスの由来)。しかし、もちろんそうする必要はありません。
それには 1 つのメソッドが定義されています。UnEscape
一方、私のフル バージョンには「別の方法」に進むメソッドEscer
もあります。これは、設定のシリアル化などに役立ちます。Escape
これにより、次のように記述できます。
CreateRecordset.Open EscerLite.UnEscape("Exec sp_Insert_item 1, 101, N'^u0126ass'"), _
conn, _
adOpenForwardOnly
ただし、独自のスキームを作成するか、単に ChrW$() 呼び出しを使用することもできます。
EscerLite.cls
Option Explicit
Private Enum UnEscStates
uesNotInEscapeSeq = 0
uesProcessingEscSeq = 1
uesProcessingLongEscSeq = 2
uesProcessingLongEscSeqXEnd = 3
uesProcessingLongEscSeqUEnd = 5
End Enum
Public Function UnEscape(ByVal EscapedText As String) As String
'Un-escape a string value. Escape sequences supported:
'
' ^xhh 7 bit hex ^r vbCr
' ^uhhhh 16 bit hex ("Unicode") ^l vbLf
' ^b vbBack ^n vbNewLine/vbCrLf
' ^t vbTab ^q quote (")
' ^v vbVerticalTab ^0 vbNullChar
' ^f vbFormFeed ^^ ^
Dim Pos As Long
Dim ChS As String
Dim ChW As Integer
Dim UpChW As Integer
Dim UnEscState As UnEscStates
Dim UnPos As Long
Dim Unicode As Boolean
Dim Accum As Long
UnEscape = Space$(Len(EscapedText))
UnPos = 1&
For Pos = 1& To Len(EscapedText)
ChS = Mid$(EscapedText, Pos, 1&)
ChW = AscW(ChS)
UpChW = AscW(UCase$(ChS))
Select Case UnEscState
Case uesNotInEscapeSeq
If ChW = 94# Then ' "^"
UnEscState = uesProcessingEscSeq
End If
Case uesProcessingEscSeq
UnEscState = uesNotInEscapeSeq
Select Case UpChW
Case 88# ' "X"
UnEscState = uesProcessingLongEscSeq
Case 85# ' "U"
Unicode = True
UnEscState = uesProcessingLongEscSeq
Case 66# ' "B"
ChS = vbBack
Case 84# ' "T"
ChS = vbTab
Case 86# ' "V"
ChS = vbVerticalTab
Case 70# ' "F"
ChS = vbFormFeed
Case 82# ' "R"
ChS = vbCr
Case 76# ' "L"
ChS = vbLf
Case 78# ' "N"
Mid$(UnEscape, UnPos, 1&) = vbCr
UnPos = UnPos + 1
ChS = vbLf
Case 81# ' "Q"
ChS = """"
Case 48# ' "0"
ChS = vbNullChar
Case 94# ' "^", i.e. ^^
'
Case Else
Err.Raise 5
End Select
Case Else
If (48# <= UpChW And UpChW <= 57#) Then
Accum = 16& * Accum + (CLng(UpChW) And &HF&)
ElseIf (65# <= UpChW And UpChW <= 70#) Then
Accum = 16& * Accum + (CLng(UpChW) - 55&)
Else
Err.Raise 5
End If
UnEscState = UnEscState + 1&
If Unicode Then
If UnEscState > uesProcessingLongEscSeqUEnd Then
ChS = ChrW$(Accum)
Accum = 0&
UnEscState = uesNotInEscapeSeq
Unicode = False
End If
Else
If Accum > 127 Then Err.Raise 5
If UnEscState > uesProcessingLongEscSeqXEnd Then
ChS = ChrW$(Accum)
Accum = 0&
UnEscState = uesNotInEscapeSeq
End If
End If
End Select
If UnEscState = uesNotInEscapeSeq Then
Mid$(UnEscape, UnPos, 1&) = ChS
UnPos = UnPos + 1&
End If
Next
If UnEscState <> uesNotInEscapeSeq Then Err.Raise 5
UnEscape = Left$(UnEscape, UnPos - 1&)
End Function
VB6がユニコードをサポートするという点であなたは正しいです。実際、VB6 文字列は本質的に Unicode ですが、適切にサポートされていないユーザー コントロールから表示または取得すると、変換中に失われるという問題があります。
UI から文字列を取得する場合は、それをサポートするテキスト ボックス コントロールを使用してください。たとえば、Microsoft Forms 2.0 Object Library への参照を追加し、これらのコントロールを標準のテキスト ボックス コントロールよりも使用します。このようにして、フォントの種類とスクリプトを Unicode をサポートするものに設定できます。
また、「StrConv」、「ChrW$」など、Unicode 文字列を操作するための組み込み関数のいくつかを確認することもできます。