Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1200to1204
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Zelle als Bild speichern beschleunigen
Reinhard
Hallo Wissende,
nachfolgender Code macht schon das was ich mir erhoffte, er nimmt die Unicode Zeichen, die von A32 bis A65535 stehen und speichert sie als gif ab.
Dazu habe ich drei Fragen.
Wieso als Gif, im Code steht doch "Bitmap"? Ändere ich in
strFile = "c:\Test\meinBild" & Format(Zei, "00000") & ".gif"
gif in bmp kommt Fehler 1004, wär mir prinzipiell für mein Vorhaben egal, ich würde das nur gerne wissen.
Der Code dauert sehr lange, hochgerechnet so 80 min. Kann man das bedeutend beschleunigen , ggfs mit anderem Code?
Warum eigentlich verschwindet Excel und ich sehe das Bildchen vor mir, daß windows einen Fehler in Excel festgestellt hat, Fehlerbericht usw.?
Wieso kann ich nicht während der Code läuft, in ein Browserfenster wie Hans W. H.wechseln um da zu surfen?
Gruß ^ Danke
Reinhard

Option Explicit
Sub Range_To_Image()
Dim objPict As Object, objChrt As Chart, Zei As Long
Dim rngImage As Range, strFile As String
On Error GoTo ErrExit
Cells(1, 3) = Timer
Application.ScreenUpdating = False
With Sheets("Tabelle1")
For Zei = 32 To 65535
Application.StatusBar = Zei
Set rngImage = Cells(Zei, 1)
rngImage.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
.PasteSpecial Format:="Bitmap", Link:=False, DisplayAsIcon:=False
Set objPict = .Shapes(.Shapes.Count)
strFile = "c:\Test\meinBild" & Format(Zei, "00000") & ".gif"
objPict.Copy
Set objChrt = .ChartObjects.Add(1, 1, objPict.Width + 8, objPict.Height + 8).Chart
objChrt.Paste
objChrt.Export strFile
objChrt.Parent.Delete
objPict.Delete
Next Zei
End With
Application.ScreenUpdating = True
Cells(2, 3) = Timer
Cells(3, 3) = Cells(2, 3) - Cells(1, 3)
Application.StatusBar = False
ErrExit:
Set objPict = Nothing
Set objChrt = Nothing
Set rngImage = Nothing
End Sub

AW: Zelle als Bild speichern beschleunigen
12.02.2011 19:49:01
Nepumuk
Hallo,
weil der Code den Prozessor und die Platte zu 100% belasten, da geht nichts mehr nebenbei. Du erzeugst schließlich 65.504 Bilder.
Versuch es mal so, dann dauert das ganze nur 3-4 Minuten. Der Code kann allerdings nur Bitmaps erstellen.
' **********************************************************************
' Modul: Modul4 Typ: Allgemeines Modul
' **********************************************************************

Option Explicit

Private Declare Function IsClipboardFormatAvailable Lib "user32.dll" ( _
    ByVal wFormat As Integer) As Long
Private Declare Function OpenClipboard Lib "user32.dll" ( _
    ByVal hWnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32.dll" ( _
    ByVal wFormat As Integer) As Long
Private Declare Function EmptyClipboard Lib "user32.dll" () As Long
Private Declare Function CloseClipboard Lib "user32.dll" () As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" ( _
    ByRef PicDesc As uPicDesc, _
    ByRef RefIID As GUID, _
    ByVal fPictureOwnsHandle As Long, _
    ByRef IPic As IPicture) As Long

Private Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7) As Byte
End Type

Private Type uPicDesc
    lngSize As Long
    lngType As Long
    lnghPic As Long
    lnghPal As Long
End Type

Private Const E_ABORT = &H80004004
Private Const E_ACCESSDENIED = &H80070005
Private Const E_FAIL = &H80004005
Private Const E_HANDLE = &H80070006
Private Const E_INVALIDARG = &H80070057
Private Const E_NOINTERFACE = &H80004002
Private Const E_NOTIMPL = &H80004001
Private Const E_OUTOFMEMORY = &H8007000E
Private Const E_POINTER = &H80004003
Private Const E_UNEXPECTED = &H8000FFFF
Private Const S_OK = &H0

Private Const CF_BITMAP = 2
Private Const IMAGE_BITMAP = 0
Private Const LR_COPYRETURNORG = &H4

Private Function Paste_Picture() As IPicture
    
    Dim lngReturn As Long, lngPointer As Long, lngCopy As Long
    
    If IsClipboardFormatAvailable(xlBitmap) <> 0 Then
        lngReturn = OpenClipboard(0&)
        If lngReturn > 0 Then
            lngPointer = GetClipboardData(CF_BITMAP)
            lngCopy = CopyImage(lngPointer, IMAGE_BITMAP, 0&, 0&, LR_COPYRETURNORG)
            Call CloseClipboard
            If lngPointer <> 0 Then _
                Set Paste_Picture = Create_Picture(lngCopy, 0, CF_BITMAP)
        End If
    End If
End Function

Private Function Create_Picture( _
        ByVal lnghPic As Long, _
        ByVal lnghPal As Long, _
        ByVal lngPicType As Long) As IPicture

    
    Dim lngReturn As Long
    Dim udtPicInfo As uPicDesc, udtIID_IDispatch As GUID
    Dim objIPicture As IPicture
    
    Const PICTYPE_BITMAP = 1
    Const PICTYPE_ENHMETAFILE = 4
    
    With udtIID_IDispatch
        .Data1 = &H7BF80980
        .Data2 = &HBF32
        .Data3 = &H101A
        .Data4(0) = &H8B
        .Data4(1) = &HBB
        .Data4(2) = &H0
        .Data4(3) = &HAA
        .Data4(4) = &H0
        .Data4(5) = &H30
        .Data4(6) = &HC
        .Data4(7) = &HAB
    End With
    
    With udtPicInfo
        .lngSize = Len(udtPicInfo)
        .lngType = PICTYPE_BITMAP
        .lnghPic = lnghPic
        .lnghPal = lnghPal
    End With
    
    lngReturn = OleCreatePictureIndirect(udtPicInfo, udtIID_IDispatch, True, objIPicture)
    
    If lngReturn <> S_OK Then
        MsgBox "Error occure " & OLEError(lngReturn), vbCritical, "Error"
    Else
        Set Create_Picture = objIPicture
    End If
    
End Function

Private Function OLEError(lngErrorNumber As Long) As String
    Select Case lngErrorNumber
        Case E_ABORT: OLEError = "Aborted"
        Case E_ACCESSDENIED: OLEError = "Access Denied"
        Case E_FAIL: OLEError = "General Failure"
        Case E_HANDLE: OLEError = "Bad/Missing Handle"
        Case E_INVALIDARG: OLEError = "Invalid Argument"
        Case E_NOINTERFACE: OLEError = "No Interface"
        Case E_NOTIMPL: OLEError = "Not Implemented"
        Case E_OUTOFMEMORY: OLEError = "Out of Memory"
        Case E_POINTER: OLEError = "Invalid Pointer"
        Case E_UNEXPECTED: OLEError = "Unknown Error"
    End Select
End Function

Private Function Save_Picture(strFileName As String) As Boolean
    
    Dim objPicture As Variant
    
    Set objPicture = Paste_Picture()
    
    If Not objPicture Is Nothing Then
        
        Call SavePicture(objPicture, strFileName)
        Save_Picture = True
        
    End If
    
End Function

Public Sub Range_To_Image()
    
    Dim lngRow As Long
    
    With Tabelle1
        
        For lngRow = 32 To 65535
            
            Call EmptyClipboard
            
            .Cells(lngRow, 1).CopyPicture Appearance:=xlScreen, Format:=xlBitmap
            
            If Not Save_Picture("C:\Test\meinBild" & Format(lngRow, "00000") & ".bmp") Then
                
                MsgBox "Not possible to create picture.", vbCritical, "Error"
                Exit For
                
            End If
        Next
    End With
End Sub

Gruß
Nepumuk
Anzeige
AW: Zelle als Bild speichern beschleunigen
12.02.2011 20:21:42
Reinhard
Hallo Max,
ich danke dir sehr, 3-4 Minuten? Genial. Mir persönlich ist bmp oder gif egal.
Hintergrund des ganzen ist die Frage, die ich hier schonmal vor locker 5 Jahren gestellt habe, danach in Online-Excel ohne weiterführende Antwort.
Wenn ich mit einer Schleife von 32 bis 65535 mit ChrW alle Unicodezeichen z.B. von Arial in entsprechenden Zellen in A darstellen lasse, so erscheinen ja nicht druckbare zeichen als Quadrat.
Meine Frage war, wie kann ich pro zeichen ermitteln ob es druckbar ist oder nicht.
Die blieb halt unbeantwortet. Nun bin ich bei sowas zäh und habe zwischenzeitlich alle 2 jahre neue Versuche unternommen, das irgendwie zu lösen. Und aktuell habe ich es geschafft *sehr freu*.
Die Lösung dauert halt lange, was natürlich lästig ist, wenn ich da die Druckbaren Zeichen aller Schriftarten von mir ermoitteln will.
Nachstehend ist dann der Code, der ermittelt ob die Zeichen druckbar sind oder nicht, aber der ist mir ausreichend schnell.
Nochmals danke, wenn ich mich nicht mehr melde, klappt alles vorzüglich *hoff*
Gruß
Reinhard
Option Explicit
Sub Vergleich()
Dim Zei As Long
Const Viereck As String = "c:\test\zeichenbilder\meinbild00129.gif"
Cells(1, 3) = Timer
Application.ScreenUpdating = False
For Zei = 32 To 65536
Application.StatusBar = Zei
Cells(Zei, 2).Value = FileEqual(Viereck, "c:\test\zeichenbilder\meinbild" & Format(Zei, " _
00000") & ".gif")
Next Zei
Application.ScreenUpdating = True
Cells(2, 3) = Timer
Cells(3, 3) = Cells(2, 3) - Cells(1, 3)
Application.StatusBar = False
End Sub
Function FileEqual(ByRef Path1 As String, ByRef Path2 As String) As Boolean
'Bei unterschiedlicher Länge abbrechen:
If FileLen(Path1)  FileLen(Path2) Then Exit Function
'Inhalte vergleichen:
FileEqual = (ReadFile(Path1) = ReadFile(Path2))
End Function
Function ReadFile(ByRef Path As String) As String
Dim FileNr As Long
'Falls nicht vorhanden, nichts zurückgeben:
On Error Resume Next
If FileLen(Path) = 0 Then Exit Function
On Error GoTo 0
'Datei einlesen:
FileNr = FreeFile
Open Path For Binary As #FileNr
ReadFile = Space$(LOF(FileNr))
Get #FileNr, , ReadFile
Close #FileNr
End Function
Sub Erzeugen()
Dim Zei As Long
Application.ScreenUpdating = False
For Zei = 32 To 65535
Cells(Zei, 1) = ChrW(Zei)
Next Zei
Application.ScreenUpdating = True
End Sub
Sub tt()
Range("f1") = Timer
End Sub

Anzeige
AW: Zelle als Bild speichern beschleunigen
12.02.2011 20:43:03
Reinhard
Hallo Nepumuk,
da fehlt noch was :-)
Es wird das bemängelt:
lngCopy = CopyImage(lngPointer, IMAGE_BITMAP, 0&, 0&, LR_COPYRETURNORG)
Weil es die Funktion CopyImage nicht gibt.
Gruß
Reinhard
AW: Zelle als Bild speichern beschleunigen
12.02.2011 20:55:37
Nepumuk
Hallo,
die Funktion stand noch in einem anderen Modul als Public, daher ist mir das nicht aufgefallen. So passt es:
' **********************************************************************
' Modul: Modul4 Typ: Allgemeines Modul
' **********************************************************************

Option Explicit

Private Declare Function IsClipboardFormatAvailable Lib "user32.dll" ( _
    ByVal wFormat As Integer) As Long
Private Declare Function OpenClipboard Lib "user32.dll" ( _
    ByVal hWnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32.dll" ( _
    ByVal wFormat As Integer) As Long
Private Declare Function EmptyClipboard Lib "user32.dll" () As Long
Private Declare Function CloseClipboard Lib "user32.dll" () As Long
Private Declare Function CopyImage Lib "user32.dll" ( _
    ByVal handle As Long, _
    ByVal un1 As Long, _
    ByVal n1 As Long, _
    ByVal n2 As Long, _
    ByVal un2 As Long) As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" ( _
    ByRef PicDesc As uPicDesc, _
    ByRef RefIID As GUID, _
    ByVal fPictureOwnsHandle As Long, _
    ByRef IPic As IPicture) As Long

Private Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7) As Byte
End Type

Private Type uPicDesc
    lngSize As Long
    lngType As Long
    lnghPic As Long
    lnghPal As Long
End Type

Private Const E_ABORT = &H80004004
Private Const E_ACCESSDENIED = &H80070005
Private Const E_FAIL = &H80004005
Private Const E_HANDLE = &H80070006
Private Const E_INVALIDARG = &H80070057
Private Const E_NOINTERFACE = &H80004002
Private Const E_NOTIMPL = &H80004001
Private Const E_OUTOFMEMORY = &H8007000E
Private Const E_POINTER = &H80004003
Private Const E_UNEXPECTED = &H8000FFFF
Private Const S_OK = &H0

Private Const CF_BITMAP = 2
Private Const IMAGE_BITMAP = 0
Private Const LR_COPYRETURNORG = &H4

Private Function Paste_Picture() As IPicture
    
    Dim lngReturn As Long, lngPointer As Long, lngCopy As Long
    
    If IsClipboardFormatAvailable(xlBitmap) <> 0 Then
        lngReturn = OpenClipboard(0&)
        If lngReturn > 0 Then
            lngPointer = GetClipboardData(CF_BITMAP)
            lngCopy = CopyImage(lngPointer, IMAGE_BITMAP, 0&, 0&, LR_COPYRETURNORG)
            Call CloseClipboard
            If lngPointer <> 0 Then _
                Set Paste_Picture = Create_Picture(lngCopy, 0, CF_BITMAP)
        End If
    End If
End Function

Private Function Create_Picture( _
        ByVal lnghPic As Long, _
        ByVal lnghPal As Long, _
        ByVal lngPicType As Long) As IPicture

    
    Dim lngReturn As Long
    Dim udtPicInfo As uPicDesc, udtIID_IDispatch As GUID
    Dim objIPicture As IPicture
    
    Const PICTYPE_BITMAP = 1
    Const PICTYPE_ENHMETAFILE = 4
    
    With udtIID_IDispatch
        .Data1 = &H7BF80980
        .Data2 = &HBF32
        .Data3 = &H101A
        .Data4(0) = &H8B
        .Data4(1) = &HBB
        .Data4(2) = &H0
        .Data4(3) = &HAA
        .Data4(4) = &H0
        .Data4(5) = &H30
        .Data4(6) = &HC
        .Data4(7) = &HAB
    End With
    
    With udtPicInfo
        .lngSize = Len(udtPicInfo)
        .lngType = PICTYPE_BITMAP
        .lnghPic = lnghPic
        .lnghPal = lnghPal
    End With
    
    lngReturn = OleCreatePictureIndirect(udtPicInfo, udtIID_IDispatch, True, objIPicture)
    
    If lngReturn <> S_OK Then
        MsgBox "Error occure " & OLEError(lngReturn), vbCritical, "Error"
    Else
        Set Create_Picture = objIPicture
    End If
    
End Function

Private Function OLEError(lngErrorNumber As Long) As String
    Select Case lngErrorNumber
        Case E_ABORT: OLEError = "Aborted"
        Case E_ACCESSDENIED: OLEError = "Access Denied"
        Case E_FAIL: OLEError = "General Failure"
        Case E_HANDLE: OLEError = "Bad/Missing Handle"
        Case E_INVALIDARG: OLEError = "Invalid Argument"
        Case E_NOINTERFACE: OLEError = "No Interface"
        Case E_NOTIMPL: OLEError = "Not Implemented"
        Case E_OUTOFMEMORY: OLEError = "Out of Memory"
        Case E_POINTER: OLEError = "Invalid Pointer"
        Case E_UNEXPECTED: OLEError = "Unknown Error"
    End Select
End Function

Private Function Save_Picture(strFileName As String) As Boolean
    
    Dim objPicture As Variant
    
    Set objPicture = Paste_Picture()
    
    If Not objPicture Is Nothing Then
        
        Call SavePicture(objPicture, strFileName)
        Save_Picture = True
        
    End If
    
End Function

Public Sub Range_To_Image()
    
    Dim lngRow As Long
    
    With Tabelle1
        
        For lngRow = 32 To 65535
            
            Call EmptyClipboard
            
            .Cells(lngRow, 1).CopyPicture Appearance:=xlScreen, Format:=xlBitmap
            
            If Not Save_Picture("C:\Test\meinBild" & Format(lngRow, "00000") & ".bmp") Then
                
                MsgBox "Not possible to create picture.", vbCritical, "Error"
                Exit For
                
            End If
        Next
    End With
End Sub

Gruß
Nepumuk
Anzeige
AW: Zelle als Bild speichern beschleunigen
12.02.2011 22:03:37
Reinhard
Hallo Nepumuk,
ich weiß nicht welchen superschnellen Rechner du hast, bei mir dauerte das ca. 50 min :-(
Okay, immerhin Verkürzungsfaktor 1/2.
Dann, aber ich denke das kriege ich alleine hin, da kam grad eben als ich meine Prozedur "Vergleich" starte auf einmal die Melung "datei nicht gefunden".
Aber bin müd, das prüfe ich morgen.
Was anderes, mal grundsätzlich gesehen, Excel weiß wenn ich sage, schreibe in Zelle Ax das Zeichen ChrW(5000) ob es da ein Quadrat abbildet oder ein Zeichen.
Wieso kann man das nicht anders ermitteln ob da ein Quadrat ist oder nicht, als durch, davon ein Bild machen, dies vergleichen mit einem "Quadrat"_bild?
Dieser Weg funktioniert ja, wenn auch lange dauernd, aber geht das nicht kürzer ohn den Umweg erstmal ein Bild zu machen, dies abzuspeichern, dann wieder einzulesen um es zu vergleichen?
Gruß
Reinhard
Anzeige
AW: Zelle als Bild speichern beschleunigen
13.02.2011 09:18:28
Nepumuk
Hallo,
ich habe es auf einen normalen Laptop getestet. Mit eingeschaltetem Virenscanner läuft es etwas über 10 Minuten, ohne 3,5 Minuten. Keine Ahnung warum das bei dir so lange dauert.
Und nein, ich weiß nicht wie das zu ermitteln wäre. Ist für mich auch völlig uninteressant da ich solche Zeichen nicht per Zufallsgenerator einsetze. Welche Erkenntnis erhoffst du dir daraus zu gewinnen?
Gruß
Nepumuk
AW: Zelle als Bild speichern beschleunigen
13.02.2011 09:58:41
Reinhard
Hallo Nepumuk,
okay, dann teste ich mal wenn ich off-line bin und nur win und Excel läuft.
Was ich mir bastelen will ist ähnlich wie eine Userform die man sich basteln kann die z.B. alle eingebauten Icons/Symbole der jeiligen Excel-Versioon anzeigt.
Oder so wie in Word wo man die einfügbaren Sonderzeichen in einem Fenster sieht und durchscrollen kann.
Und da würde ich halt, abhängig je Schriftart, die "Quadrate" herausfiltern, da es davon gewaltig viele gibt.
Sehr lästig wenn ich z.B. das Zeichen für einen Notenschlüssel suche und die Unicode Nummer nicht weiß.
Ich hatte schon vor langer Zeit versucht die jeweilige Schriftart-TTF auszulesen, kam da aber zu keinem Erfolg.
Da ich den Code ja pro Schriftart nur einmal brauche bedeutet das halt mehrere Nächte wo der PC durchlaufen muß.
So, jetzt schaue ich mal warum da eine Bilddatei nicht gefunden wurde.
Gruß
Reinhard
Anzeige
AW: Zelle als Bild speichern beschleunigen
13.02.2011 10:30:42
Nepumuk
Hallo,
ab Excel2002 kannst du die Zeichentabelle direkt aus Excel heraus aufrufen. Du machst also etwas was nur für die Version 2000 und kleiner Sinn? hat. Warum nicht einfach per Makro diesen Dialog aufrufen?
Public Sub test()
    Shell "CharMap.exe", vbNormalFocus
End Sub

Gruß
Nepumuk
Anzeige
AW: Zelle als Bild speichern beschleunigen
13.02.2011 18:40:46
Reinhard
Hallo Nepumuk,
interessant, ich habe auch XL2007 Home & Student, mal schauen wie ich da die Zeichentabelle direkt aufrufe und wie das aussieht.
Dieses Charmap.exe kenne ich irgendwie, als ob schon mal benutzt *grübel*
Ich muß das jetzt erstmal austeseten, auch mit dem "Zeichnesatz" und "Gruppieren nach".
Denn bei z.B. "Arial" sehe ich da nur 1408 Zeichen, ich meine aber wenn ich alle Unicodezeichen in Arial nehme die nicht als "Quadrat" dargestellt werden sind das mehr.
Wie auch immer, ist jetzt eine spontane Antwort auf deinen Hinweis.
Ich muß das erstmal durchschauen. Noch dazu, sind in meinen Codes irgendwie noch Fehler, oder ich verletzte Limits von WinXP in Bezug auf Dateianzahl in einem Ordner.
Jedenfalls trotz Schleife bis 65535 wurden nur dateien bis zum Index 56xxx erzeugt.
Aber das ist lösbar und keine Bitte um Hilfe.
Zum Sinn, egal Charmap.exe oder die noch ungesehenen darstellungsmöglichkeiten von Zeichensätzen in 2002 +
Ich würde halt sehr gerne selbst bestimmen wie die Anzeige aussieht. Natürlich muß ich nicht jedes Rad neu erfinden. Ich sehe schon zu daß ich wie auch immer, z.B. von der Unicode-Seite im Web deren Gruppierungen und Namenseinteilungen wie latin, Griechisch usw. übernehme.
Danke für deine Hilfe, ich schaue jetzt erstmal daß ich die Codes so anpasse, sodaß die sauber laufen und ich eine vorzeigbare Mappe habe, nicht das Testrtrümmerfeld wie grad :-))
Gleichzeitig mal die charmap.exe austesten und das was du da mit Zeichensatzdarstellung ab 2002 meinst.
PS: Kann es sein daß du 2005 noch nicht Nepumuk warst sondern under Vornamen, Nachnamen, Ort geschrieben hast? Ich suchte wegen etwas völlig anderem im Inet und stolperte darüber.
Gruß
Reinhard
Anzeige
AW: Zelle als Bild speichern beschleunigen
13.02.2011 23:42:02
Nepumuk
Hallo Reinhard,
ich habe im Jahr 2000 die ersten Beiträge im Forum geschrieben und bin schon seit dem ersten Beitrag unter dem Namen Nepumuk unterwegs.
Gruß
Nepumuk
AW: Zelle als Bild speichern beschleunigen
14.02.2011 00:36:59
Reinhard
Hallo Nepumuk,
mag sein, und ist letztlich auch nicht wichtig, jedenfalls stiess ich wie gesagt, nur zeitlich zufällig wegen etwas anderem, darauf daß du da wohl damals deine Codes wie gesagt mit Namen, Vorname. Ort gekennzeichnet hast.
Gruß
Reinhard
AW: Zelle als Bild speichern beschleunigen
14.02.2011 12:04:02
Nepumuk
Hallo Reinhard,
das sind die Beispiele in Online-Excel. Peter wollte das so.
Gruß
Nepumuk

304 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige