< návrat zpět

MS Excel


Téma: VBA náhledy orbázků z jiných listů rss

Zaslal/a 2.8.2025 20:24

Ahoj,
mámm problém s kopírováním orbázků z jiných listů.
Na prvním listu mám výplně, přes prefix a ID hledám v tabulce na drhuém listu. Kliknu na výpln a vedle se mi zobrazí náhled - obrázek z druhého listu.
Ale někdy se mi náhled zobrazí jako prázdný, tedy obrázek se nezkopíruje. Někdy dostanu chybu 1004 Metoda CopyPicture třídy Range selhala. Jindy mi to jede bez problému. Nerozumím kde je problém :-/

Pokud dostanu 1004, je to zde: If Not foundPic Then wsList.Range("B" & dataRow).CopyPicture xlScreen

ublic Sub DisplayPreview(prefix As String, ID As Long)
Dim wsMap As Worksheet: Set wsMap = ThisWorkbook.Sheets(MapSheetName)
Dim wsList As Worksheet: Set wsList = ThisWorkbook.Sheets(GetListName(prefix))
Dim foundCell As Range, dataRow As Long
Dim shpCandidate As Shape, foundPic As Boolean
Dim areaR As Range, s As Shape
Dim previewShape As Shape
Dim origW As Double, origH As Double, scaleRatio As Double

' Turn off screen updating to avoid flicker
Application.ScreenUpdating = False

LastPrefix = prefix
LastID = ID
Set areaR = wsMap.Range(PreviewAreaRange)

' Find row
With wsList.Columns("A")
Set foundCell = .Find(CStr(ID), , xlValues, xlWhole)
If foundCell Is Nothing Then
Application.ScreenUpdating = True
Exit Sub
End If
dataRow = foundCell.Row
End With

' Remove existing preview named PreviewPic
On Error Resume Next
wsMap.Shapes("PreviewPic").Delete
On Error GoTo 0

' Copy picture
foundPic = False
For Each shpCandidate In wsList.Shapes
If shpCandidate.TopLeftCell.Row = dataRow And shpCandidate.TopLeftCell.Column = 2 Then
shpCandidate.Copy
foundPic = True
Exit For
End If
Next shpCandidate
If Not foundPic Then wsList.Range("B" & dataRow).CopyPicture xlScreen, xlPicture

' Paste as Picture object
Dim picObj As Picture
On Error Resume Next
Set picObj = wsMap.Pictures.Paste
On Error GoTo 0
If picObj Is Nothing Then
Application.ScreenUpdating = True
Exit Sub
End If
Set previewShape = picObj.ShapeRange(1)
previewShape.Name = "PreviewPic"

' Scale and position
origW = previewShape.Width: origH = previewShape.Height
scaleRatio = Application.Min(areaR.Width / origW, areaR.Height / origH)
With previewShape
.LockAspectRatio = msoTrue
.Width = origW * scaleRatio
.Height = origH * scaleRatio
.Left = areaR.Left + (areaR.Width - .Width) / 2
.Top = areaR.Top + (areaR.Height - .Height) / 2
End With

' Set description
wsMap.Range(PreviewDescName).Value = wsList.Range("C" & dataRow).Value

' Restore screen updating
Application.ScreenUpdating = True
End Sub

Moc díky za jakokouliv radu

Zaslat odpověď >

#057658
nio313
Nejlepší fix s nejvyšší spolehlivostí bez Range.CopyPicture

Ty už primárně hledáš Shape na řádku (obrázek v B sloupci). Tak to využij a exportuj Shape do PNG a pak ho vlož jako obrázek. Tím úplně obejdeš clipboard a CopyPicture.

Shape - PNG - vložit do náhledu

Výhoda: funguje stabilně i když list není aktivní, žádné 1004 z CopyPicture.

Public Sub DisplayPreview(prefix As String, ID As Long)
Dim wsMap As Worksheet: Set wsMap = ThisWorkbook.Sheets(MapSheetName)
Dim wsList As Worksheet: Set wsList = ThisWorkbook.Sheets(GetListName(prefix))
Dim foundCell As Range, dataRow As Long
Dim shpCandidate As Shape, srcShape As Shape
Dim areaR As Range
Dim previewShape As Shape
Dim origW As Double, origH As Double, scaleRatio As Double
Dim tmpPng As String

On Error GoTo CleanFail

Application.ScreenUpdating = False
Application.EnableEvents = False

LastPrefix = prefix
LastID = ID
Set areaR = wsMap.Range(PreviewAreaRange)

' Najdi řádek podle ID
With wsList.Columns("A")
Set foundCell = .Find(What:=CStr(ID), LookIn:=xlValues, LookAt:=xlWhole)
If foundCell Is Nothing Then GoTo CleanExit
dataRow = foundCell.Row
End With

' Smazat starý náhled
On Error Resume Next
wsMap.Shapes("PreviewPic").Delete
On Error GoTo CleanFail

' Najdi obrázek (Shape) v buňce B na daném řádku
Set srcShape = Nothing
For Each shpCandidate In wsList.Shapes
If shpCandidate.TopLeftCell.Row = dataRow And shpCandidate.TopLeftCell.Column = 2 Then
Set srcShape = shpCandidate
Exit For
End If
Next shpCandidate

If srcShape Is Nothing Then
' Pokud nemáš Shape, tak aspoň fallback na text/desc a konec
wsMap.Range(PreviewDescName).Value = wsList.Range("C" & dataRow).Value
GoTo CleanExit
End If

' Export shape do PNG (TEMP)
tmpPng = Environ$("TEMP") & "\PreviewPic_" & prefix & "_" & CStr(ID) & ".png"
On Error Resume Next
Kill tmpPng
On Error GoTo CleanFail
srcShape.Export Filename:=tmpPng, FilterName:="PNG"

' Vložit PNG do map sheetu jako picture/shape
Set previewShape = wsMap.Shapes.AddPicture( _
Filename:=tmpPng, _
LinkToFile:=msoFalse, _
SaveWithDocument:=msoTrue, _
Left:=areaR.Left, Top:=areaR.Top, Width:=-1, Height:=-1)

previewShape.Name = "PreviewPic"

' Scale + centrování do PreviewArea
origW = previewShape.Width: origH = previewShape.Height
scaleRatio = Application.Min(areaR.Width / origW, areaR.Height / origH)

With previewShape
.LockAspectRatio = msoTrue
.Width = origW * scaleRatio
.Height = origH * scaleRatio
.Left = areaR.Left + (areaR.Width - .Width) / 2
.Top = areaR.Top + (areaR.Height - .Height) / 2
End With

' Popisek
wsMap.Range(PreviewDescName).Value = wsList.Range("C" & dataRow).Value

CleanExit:
Application.CutCopyMode = False
Application.EnableEvents = True
Application.ScreenUpdating = True
Exit Sub

CleanFail:
' Když něco selže, radši se vrať do konzistentního stavu
Application.CutCopyMode = False
Application.EnableEvents = True
Application.ScreenUpdating = True
' volitelně: Debug.Print Err.Number, Err.Description
End Subcitovat

Uživatelské menu

Nejste přihlášen(a)
avatar\n

Formulář Faktura

Formulář Faktura IV

Oblíbený formulář Faktura byl vylepšen a rozšířen.
Více se dočtete zde.

Helios iNuvio

Používáte podnikový systém Helios iNuvio? Potřebujete pomoci se správou nebo vyvinout SQL proceduru? Více informací naleznete na stránce Helios iNuvio.

On-line nástroje