String als UTF8?

DrMueller

Erfahrenes Mitglied
Hallo Leute,

folgendes: Wir erhalten eine Email, welche im Text z.B. tschechische Zeichen erhält.
Wir müssen jedoch, um einige unerwünschte Zeichen rauszufiltern, den Body per Replace neu setzen.
Nun wird hier ja body --> string --> body gemacht, und anscheinend werden dabei die tschechischen Zeichen vermurkst resp. rausgelöscht.
Daher meine Frage:
Gibt es eine Möglichkeit, ein Replace per String zu machen, wobei der String als uft8 definiert wird?

Oder gibt es da evtl. eine andere Möglichkeit dies zu umgehen? Die Alternative wäre ja, dass nicht der ganze Body per String durchgelaufen wird, sondern nur die Zeichen, die nicht erwünscht sind, entfernt werden.

Natürlich wäre die erste Variante viel sauberer.



Wie immer danke ich vielmals im Voraus für alle Antworten.


Müller Matthias
 
Ich tippe mal darauf, dass irgendwo von Unicode in ANSI umgewandelt wird. Lest ihr die Mail bzw. den Body in eine Textbox ein? Ich hab gelesen, dass die VB6-eigene Textbox Probleme hat, Unicode-Zeichen darzustellen, welche vorher nicht explizit nach Unicode umgewandelt worden sind.

Auf die schnelle habe ich das hier gefunden: http://www.cyberactivex.com/UnicodeTutorialVb.htm

Alternative: Den Body nicht in einen String einlesen, sondern in ein Byte-Array, und dann die zu ersetzenden Zeichen per ASCII-Code suchen/ersetzen.
 
Wir machen eigentlich nur folgendes

Visual Basic:
mb.BodyText = Replace(mb.BodyText, Chr(18), "'")


Aber auch so was wie
Visual Basic:
mb.BodyText = mb.ToUTF8(Replace(mb.BodyText, Chr(18), "'"), mb.CharsetOriginal)


funktioniert nicht, daher muss es doch fast am String selber liegen.
 
Was is mb für ein Objekt? Ist BodyText ne reine Eigenschaft oder passiert dort noch was innerhalb der Let Property-Prozedur? Habt ihr mal nen HexDump gemacht für Original-String und bearbeiteten String?

HexDump ist eine Funktion von Bruce McKinney, welches du im Modul im Anhang finden kannst. Einfach von txt in bas umbenennen.

Die Beschreibung, wie der HexDump funktioniert steht hier: http://vb.mvps.org/hardcore/html/whatisunicode.htm
 

Anhänge

  • Utility.txt
    38,1 KB · Aufrufe: 33
Anscheinend war's doch das Objekt. Der String wird das richit geliefert haben, das Objekt selber aber falsch. Ich habe da testweise ein kleines Bytereplace programmiert:

Evtl. kann das auch wer brauchen, ist für einzelne Zeichen sehr viel schneller als der replace per String, halt das MB wegmachen:

Visual Basic:
    Dim thisBodyText() As Byte
    ReDim thisBodyText(Len(mb.BodyText) - 1) As Byte
    Dim thisBCount As Long
    thisBodyText() = StrConv(mb.BodyText, vbFromUnicode)
    For thisbCount = 0 To UBound(thisBodyText)
      If thisBodyText(thisbCount) = Asc(Chr$(18)) Then
        thisBodyText(thisbCount) = Asc("'")
      End If
    Next thisbCount
    mb.BodyText = mb.ToUTF8(StrConv(thisBodyText, vbUnicode), mb.CharsetOriginal)

War aber nicht die Lösung, tatsächlich musste ich das Charset manuell umstellen. Ich lese dazu den Text aus und prüfe auf Sprachen, derzeit nur auf slowakisch:

Visual Basic:
Private Function containsCyrillicLanguage(mText As String) As Boolean
  On Error GoTo containsCyrillicLanguage_Error
  Dim thisReturnValue As Boolean
  mText = Replace$(mText, "=3D", "=", , , vbTextCompare) '=3d ist ein = bei quoted printable
  If InStr(1, mText, "LANG=SL", vbTextCompare) Then
    thisReturnValue = True
  End If

containsCyrillicLanguage_Ende:
  On Error Resume Next
  containsCyrillicLanguage = thisReturnValue
  Exit Function


So MUSS man den Charset, egal was angegeben ist, übersteuern. Bei Bedarf wird hier einfach das Instr aufg andere Sprachen erweitert.
 
Um in deiner Funktion zu bleiben

Visual Basic:
Private Function containsCyrillicLanguage(mText As String) As Boolean
  On Error Resume Next
  Dim thisReturnValue As Boolean

  'Mein Einwurf
  thisReturnValue=False

  mText = Replace$(mText, "=3D", "=", , , vbTextCompare) '=3d ist ein = bei quoted printable
  If InStr(1, mText, "LANG=SL", vbTextCompare) Then
    thisReturnValue = True
  End If
  containsCyrillicLanguage = thisReturnValue
  Exit Function

Ich setze von vornherein einen Fehlschlag voraus, und nur wenn die If-Abfrage positiv beantwortet wird, bekommt thisReturnValue True. Somit kann ich mir das Goto-Gedöns sparen, und muss nur ein On Error Resume Next als erste Zeile setzen.

Bin mir jetzt nicht sicher aber ich glaube man könnte das ganze auch so machen

Visual Basic:
Private Function containsCyrillicLanguage(mText As String) As Boolean
  On Error Resume Next
  containsCyrillicLanguage = False 'Fehlschlag voraussetzen
  mText = Replace$(mText, "=3D", "=", , , vbTextCompare) '=3d ist ein = bei quoted printable
  containsCyrillicLanguage = InStr(1, mText, "LANG=SL", vbTextCompare)
  'Wird der gesuchte Text nicht gefunden, gibt InStr 0 zurück (=False), ansonsten die Position des ersten Auftretens, was automatisch in True umgewandelt wird, da es ungleich bzw. grösser 0 sein muss

  Exit Function
 
Den returnvalue auf false zu setzen bringt ja nichts, ein bool ist ja immer false beim initialisieren.
Ich halte einen Errorhandler bei einem grossen Projekt immer für sehr wichtig, da die Fehlersuche ansonsten sehr mühsam wird.

Wir haben folgendes Abfangen des Fehlers als Stanrd im Einsatz:

Visual Basic:
decodeMyFile_Ende:
  On Error Resume Next
  'Objekte auf nothing setzen...
  Exit Function

decodeMyFile_Error:
  Debug.Print Err.Description & "(" & Err.Number & ")" & " decodeMyFile in clsDocHnd "
  Debug.Assert (Err = False)
  On Error Resume Next
  WriteDBGView Err.Description & "(" & Err.Number & ")" & " decodeMyFile in clsDocHnd ", App.EXEName 'MLHIDE
  GoTo decodeMyFile_Ende
  Resume


So sieht man den Fehler im Debugviewer und wenn er beim Debuggen auftritt, kommt man automatisch zum Fehler.
 
Ach so! Ich dachte du beziehst dich auf deine Funktion. Klar haste recht, dass in grossen Projekten Errorhandler zu coden sind. Ich bezog mich nur auf deine Funktion, weil die einzige Stelle, wo es da knallen kann ist der Replace, und da ist IMHO ein Errorhandler überflüssig, es sei denn du willst die Fehlerbeschreibung wissen, dann gehts ja gar nicht anderst wie in deinem Code oben.
 

Neue Beiträge

Zurück