Nichtdruckbare Zeichen in Unicode

Hallo Wissende,
Unicode umfasst 65536 Zeichen, je nach gewählter Schriftart zeigt Excel bei dem Code:

For Z = 0 to 65535
 Cells(z+1,1)=ChrW(Z)
next Z

entweder das Zeichen an, oder wenn das nicht geht ein kleines Quadrat.

Ich mutmaße, das ist in VB gleich, wenn ihr das in eine Tetbox schreiben läßt.

Nun sind das recht viele Quadrate und ich würde gerne alle Zeilen mt diesen Quadraten liquidieren.

Dummerweise geht das nicht mit =AscW(Zelle) diese Quadrate zu erkennen.
Bis heute fand ich, auch mit Nachfrage in Excelforen, keine Möglichkeit, die Zellen mit Quadraten zu entfernen.

Jetzt fand ich aber einen Dreh um sie einigermaßen zu erkennen.
Ich habe Vba-Code zusammengebastelt, der (in Spalte A sind alle 65536 Zeichen untereinander aufgelistet) jede Zelle durchgeht, diese als Bild kopiert, in ein Exceldiagramm als Bild einfügt und dann dieses Bild als .JPG abspeichert.

Ohne den Umweg über ein Diagramm kenne ich keinen Weg eine Zelle als Bild abzuspeichern, nur da gibt es eine Export-Function.

Mit PutInClipboard kann ich nur Text als Text in die Zwischenablage schaufeln, nicht als Bild des Textes.

Dann lese ich die Dateilänge (FileLen) der Bildatei aus undsiehe da, die Bilddateien der Zellen die nur ein Quadrat zeigen haben immer die gleiche Größe.
Abgesehen von wenigen lästigen Ausreißern haben Bilder von Zellen die ausdruckbare Zeichen enthalten eine unterschiedliche Dateigröße.

Das Problem ist nun, der Code dauert mehrere Stunden bei 65536 Zellen :frowning: und sowas ist absolut nix für meine Ungeduld *rumhippel* :smile:

Dann probierte ich etwas anderes, in einer Userform habe ich eine Textbox, in ihr ist Autosize auf True gestellt, dorthinein schreibe ich nacheinander alle 65536 Zeichen aus Unicode und ermittle Widht der Textbox.
Leider haben da vielzuviel Zeichen die gleiche Breite wie ein Quadrat:frowning:

**Was ich also suche ist eine schnelle Funktion

Function IsPrintable(Chraracter as Long, Font as String)
’ das was hier fehlt suche ich :smile:
end Function**

Ich freue mich über jede Idee, anderen Ansatz.

Nachfolgend der „langsame“ Code.
Und Nepumuks (ein Excel-Vba-Profi) Code war für etwas anderes bestimmt, ich habe ihn reichlich zerpflückt, beim Testen kriegte ich dann aber massivste Abstürze und es hat teilweise mein Excel zerschossen, an dieser Stelle Dank an die Excelprogrammierer, die Fehlermeldung „Datei fehlt“ finde ich schon super Klasse, da kann ich sofort ablesen welche und wo, in den Verweisen, in den Add-Ins, in der Personl.xls, sonstwo *grummel*

Aus diesem Grund ist mein Code schon vom Aufbau her langsam, aber funktioniert ohne Abstürze, Tuning kommt später.
Ist schon klar, daß 65536 mal ein Blatt anlegen und löschen ein wenig bremst *gg*

Der Absturz kam meist, aber Excel ist da variantenreich, bei:
ActiveSheet.Pictures.Paste Link:=True
und logo, wenn schon denn schon, Pictures wird nicht in der Hilfe erklärt:frowning:

Danke ^ Gruß
Reinhard

Option Explicit
Public B(65535, 1) As String
'
Sub test()
Dim Z As Long
ActiveSheet.UsedRange.ClearContents
Application.ScreenUpdating = False
Call Zeichen
For Z = 1 To 65536
 Application.StatusBar = Right("00000" & Z, 5) & " / 65536 Zellen"
 Call prcExportTablecopy3(Worksheets("Tabelle1").Cells(Z, 1))
Next Z
ActiveSheet.Range("A1:B65536") = B
Application.StatusBar = ""
Application.ScreenUpdating = True
End Sub
'
Public Sub prcExportTablecopy3(Zelle As Range)
'Code ist von Nepumuk. 2006
 Dim objChart As Chart
 Dim objChartObject As ChartObject
 Dim objShape As Shape
 Application.ScreenUpdating = False
 Zelle.Copy
 ActiveSheet.Pictures.Paste Link:=True
 'Application.CommandBars("Picture").Visible = False
 Application.CutCopyMode = False
 Set objShape = ActiveSheet.Shapes(ActiveSheet.Shapes.Count)
 objShape.CopyPicture Appearance:=2, Format:=-4147
 Set objChart = Charts.Add
 Set objChartObject = objChart.ChartObjects.Add(0, 0, \_
 objShape.Width, objShape.Height)
 With objChartObject.Chart
 .Paste
 .Export FileName:="C:\Bilder\Bild.jpg", \_
 FilterName:="JPG", Interactive:=False
 End With
 'Zelle.Offset(0, 1) = FileLen("C:\Bilder\Bild.jpg")
 B(Zelle.Row - 1, 1) = FileLen("C:\Bilder\Bild.jpg")
 Kill "C:\Bilder\Bild.jpg"
 Application.DisplayAlerts = False
 objChart.Delete
 objShape.Delete
 Application.DisplayAlerts = True
 Set objChart = Nothing
 Set objChartObject = Nothing
 Set objShape = Nothing
End Sub
'
Sub Zeichen()
Dim Z As Long
Application.ScreenUpdating = False
Application.StatusBar = "Bitte warten, Initialisierung läuft..."
For Z = 0 To 65535
 'Application.StatusBar = Right("00000" & Z, 5) & " / 65536 Zellen"
 B(Z, 0) = ChrW(Z) & ChrW(Z) & ChrW(Z)
Next Z
ActiveSheet.Range("A1:B65536") = B
Application.ScreenUpdating = True
Application.StatusBar = ""
End Sub

Hallo Reinhard,

sichern und die Dateigröße vergleichen ist nach meiner Meinung die schlechteste Lösung. 1.) Langsam, 2.) Ungenau.

Eigentlich hatte ich angenommen, daß das hier …

Private Sub Command2\_Click()
 MSFlexGrid1.TextMatrix(1, 1) = ChrW(1&amp:wink:
 MSFlexGrid2.TextMatrix(1, 1) = ChrW(60000)
 For z = 0 To 65535
 MSFlexGrid3.TextMatrix(1, 1) = ChrW(z)
 If MSFlexGrid3.Picture MSFlexGrid1.Picture And MSFlexGrid3.Picture MSFlexGrid2.Picture Then
 List1.AddItem CStr(z) + " : " + ChrW(z)
 DoEvents
 End If
 Next
End Sub

… funktioniert, tut es aber nicht. Da muss ich etwas falsch verstanden haben.

Aber das hier:

Private Type BITMAP
 bmType As Long
 bmWidth As Long
 bmHeight As Long
 bmWidthBytes As Long
 bmPlanes As Integer
 bmBitsPixel As Integer
 bmBits As Long
End Type
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Dim PicBits() As Byte, PicInfo As BITMAP
Dim Cnt As Long, BytesPerLine As Long
Private Sub Command1\_Click()
 Dim PicStr1 As String, PicStr2 As String, PicStr3 As String
 Dim z As Long
 MSFlexGrid1.Clear
 MSFlexGrid1.TextMatrix(1, 1) = ChrW(1&amp:wink:
 GetObject MSFlexGrid1.Picture, Len(PicInfo), PicInfo
 BytesPerLine = (PicInfo.bmWidth \* 3 + 3) And &HFFFFFFFC
 ReDim PicBits(1 To BytesPerLine \* PicInfo.bmHeight \* 3) As Byte
 GetBitmapBits MSFlexGrid1.Picture, UBound(PicBits), PicBits(1)
 PicStr1 = Space(UBound(PicBits) / 2)
 CopyMemory ByVal StrPtr(PicStr1), PicBits(1), UBound(PicBits)
 MSFlexGrid1.Clear
 MSFlexGrid1.TextMatrix(1, 1) = ChrW(60000)
 GetBitmapBits MSFlexGrid1.Picture, UBound(PicBits), PicBits(1)
 PicStr2 = Space(UBound(PicBits) / 2)
 CopyMemory ByVal StrPtr(PicStr2), PicBits(1), UBound(PicBits)
 PicStr3 = Space(UBound(PicBits) / 2)
 For z = 0 To 65535
 MSFlexGrid1.TextMatrix(1, 1) = ChrW(z)
 GetBitmapBits MSFlexGrid1.Picture, UBound(PicBits), PicBits(1)
 CopyMemory ByVal StrPtr(PicStr3), PicBits(1), UBound(PicBits)
 If PicStr3 PicStr2 And PicStr3 PicStr1 Then
 List1.AddItem CStr(z) + " : " + ChrW(z)
 DoEvents
 End If
 Next
End Sub

… funktioniert, ist mit Sicherheit schneller und vergleicht vor allem die Bitmuster. Zwei gleich große Bilder mit identisch vielen schwarzen Pixeln, nur unterschiedliche Muster, werden auch unterschieden, es gibt also keine ‚Ausreißer‘. :smile:

Etwas Besseres habe ich leider auch nicht gefunden. :frowning:

Gruß, Rainer

Hallo Rainer,

… funktioniert, tut es aber nicht. Da muss ich etwas falsch
verstanden haben.

an meiner Anfrage? Ich will doch „nur“ *gg* wissen welche Zeichen des Unicodes druckbar sind.

Zumindest in Excel, je nach eingestellter Schriftart.

Wenn denn mal mein Traum klappt und du oder .Net-Axel :smile: basteln mir was wodurch ich aus excel heraus in den hiesigen Community-Chat was reinschreiben kann, dann wirds noch komplizierter, bedeutend komplizierter, denn dort ist ein Zeichensatz X eingestellt, d.h. die evtl. Liste in Excel welche Zeichen druckbar/sichtbar sind, kann man in die Tonne kippen, denn der „Filter“ des Chatfenster macht, wenn er z.B das in Excel angezeigte dezimale Zeichen 9876 anzeigen soll, daß was er will damit, also er zeigt nix an oder das Zeichen wie in Excel, oder halt ein anders aussehendes Zeichen.
Oder, in Excel wird Zeichen 4711 nicht dargestellt, im Chat schon.

Okay, diese Problematik kommt später *Erstmal schon*

… funktioniert, ist mit Sicherheit schneller und vergleicht
vor allem die Bitmuster. Zwei gleich große Bilder mit
identisch vielen schwarzen Pixeln, nur unterschiedliche
Muster, werden auch unterschieden, es gibt also keine
‚Ausreißer‘. :smile:

Etwas Besseres habe ich leider auch nicht gefunden. :frowning:

Ich probiere das, danke dir erstmal.
„Keine Ausreißer“ ist schon mal sehr gut.

„Mein“ Code lief noch nie bis zum Ende, immer Absturz :frowning:

Gruß
Reinhard

Hallo Reinhard,

… funktioniert, tut es aber nicht. Da muss ich etwas falsch
verstanden haben.

an meiner Anfrage?

Nein, in VB. :smile:

Ich will doch „nur“ *gg* wissen welche
Zeichen des Unicodes druckbar sind.

Zumindest in Excel, je nach eingestellter Schriftart.

Wenn denn mal mein Traum klappt und du oder .Net-Axel :smile:
basteln mir was wodurch ich aus excel heraus in den hiesigen
Community-Chat was reinschreiben kann, dann wirds noch
komplizierter, bedeutend komplizierter, denn dort ist ein
Zeichensatz X eingestellt, d.h. die evtl. Liste in Excel
welche Zeichen druckbar/sichtbar sind, kann man in die Tonne
kippen, denn der „Filter“ des Chatfenster macht, wenn er z.B
das in Excel angezeigte dezimale Zeichen 9876 anzeigen soll,
daß was er will damit, also er zeigt nix an oder das Zeichen
wie in Excel, oder halt ein anders aussehendes Zeichen.
Oder, in Excel wird Zeichen 4711 nicht dargestellt, im Chat
schon.

Es wird noch komplizierter. :smile: Welche Zeichen dargestellt werden entscheidet sich erst auf dem Computer des Users, der den Beitrag liest. Du erinnerst Dich an die temporäre Angewohnheit eines anderen Users eine Chinesische Unterschrift einzufügen? Hier konnte ich die sehen, in der Firma nicht.

Okay, diese Problematik kommt später *Erstmal schon*

… funktioniert, ist mit Sicherheit schneller und vergleicht
vor allem die Bitmuster. Zwei gleich große Bilder mit
identisch vielen schwarzen Pixeln, nur unterschiedliche
Muster, werden auch unterschieden, es gibt also keine
‚Ausreißer‘. :smile:

Etwas Besseres habe ich leider auch nicht gefunden. :frowning:

Ich probiere das, danke dir erstmal.
„Keine Ausreißer“ ist schon mal sehr gut.

„Mein“ Code lief noch nie bis zum Ende, immer Absturz :frowning:

Dann schreib das mal für Dich um, der Code läuft bei mir nur wenige Sekunden.

Gruß, Rainer

Hallo Rainer,
ich kam noch nicht dazu es zu testen.
Aber das kommt noch, wollte nur mal eine kurze Rückmeldung geben.
Lieben Gruß
Reinhard