0

VB6アプリケーションを使用していますが、Unicode文字を保存しようとすると、MsSQLデータベースに正しく保存されません。SSMSで直接挿入ステートメントを実行すると、挿入は正しく実行されます。

Exec sp_Insert_item 1, 101, N'Ħass'

接続文字列のドライバーとしてSQLOLEDBを使用しており、列はNVarcharとして設定されています

誰かがこの問題を解決する方法を知っていますか?

ありがとう、アラン

4

2 に答える 2

0

あなたの問題は、利用可能なほとんどのコントロールで遭遇する 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
于 2012-05-09T19:40:52.577 に答える
0

VB6がユニコードをサポートするという点であなたは正しいです。実際、VB6 文字列は本質的に Unicode ですが、適切にサポートされていないユーザー コントロールから表示または取得すると、変換中に失われるという問題があります。

UI から文字列を取得する場合は、それをサポートするテキスト ボックス コントロールを使用してください。たとえば、Microsoft Forms 2.0 Object Library への参照を追加し、これらのコントロールを標準のテキスト ボックス コントロールよりも使用します。このようにして、フォントの種類とスクリプトを Unicode をサポートするものに設定できます。

また、「StrConv」、「ChrW$」など、Unicode 文字列を操作するための組み込み関数のいくつかを確認することもできます。

于 2012-05-09T03:36:24.073 に答える