VBA Fill a text box with a picture in a worksheet

Paul B

Well-known Member
Joined
Feb 15, 2002
Messages
577
I know you can fill a text box with a picture from a file, like the code below, but can you fill it with a picture that is in the workbook?
Excel 2003


Code:
   .Fill.UserPicture picturefile:=Application.DefaultFilePath _
                        & "\My Pictures\" & "\Error.jpg"
 

Excel Facts

Can you AutoAverage in Excel?
There is a drop-down next to the AutoSum symbol. Open the drop-down to choose AVERAGE, COUNT, MAX, or MIN
I know you can fill a text box with a picture from a file, like the code below, but can you fill it with a picture that is in the workbook?
Excel 2003


Code:
   .Fill.UserPicture picturefile:=Application.DefaultFilePath _
                        & "\My Pictures\" & "\Error.jpg"


you need to know the picture name in the workbook. need to refer to activesheet and the picture name (default is Picture 1)

only way i can think of
 
Upvote 0
tried
.Fill.UserPicture picturefile:=Sheet5.Shapes("Error")
but that did not work
 
Upvote 0
Kenneth, could not make it work, but I did find this and got it to work, looks like you have to export the picture and then bring it back in to fill the textbox, this makes a range a picture, which gets the picture in that range, and not just exports the picture, works ok but just thought there might be a way to export the picture itself

Code:
Private Sub SaveRngAsJPG(Rng As Range, FileName As String)
Dim Cht As Chart, bScreen As Boolean, Shp As Shape
bScreen = Application.ScreenUpdating
Application.ScreenUpdating = False
Set Cht = Workbooks.Add(xlChart).Charts(1)
Cht.ChartArea.Clear
Rng.CopyPicture xlScreen, xlPicture
Cht.Paste
With Cht.Shapes(1)
.Left = 0
.Top = 0
.Width = Cht.ChartArea.Width
.Height = Cht.ChartArea.Height
End With
Cht.Export FileName, "JPEG", False
Cht.Parent.Close False
Application.ScreenUpdating = bScreen
End Sub

Sub MakeErrorPic()
Dim Rng As Range, Fn As String
Set Rng = Sheet5.Range("AA1")
Fn = Application.DefaultFilePath & "\ExcelErrorPicture.jpg"
SaveRngAsJPG Rng, Fn
End Sub


'then use this
    .Fill.UserPicture picturefile:=Application.DefaultFilePath & "\ExcelErrorPicture.jpg"
 
Upvote 0
I usually save my solutions but this is one that I don't use often. I will look into this late tomorrow. I am sure that I have done it before or something close to it.
 
Upvote 0
Module1:
Code:
Sub Test_TextBoxShapeFill()
  TextBoxShapeFill ActiveSheet.Shapes("Right Arrow 1"), ActiveSheet.Shapes("TextBox 1")
End Sub

Sub TextBoxShapeFill(ashp As Shape, sTB As Shape)
  Dim oPic As IPictureDisp, sFile As String
  'aShp.CopyPicture xlScreen, xlBitmap
  ashp.CopyPicture xlScreen, xlPrinter
  'Retrieve the picture from the clipboard...
  Set oPic = PastePicture(xlBitmap)
  sFile = GetWinTemp & "\TexBoxShapeFill.bmp"
  SavePicture oPic, sFile
  sTB.Fill.UserPicture (sFile)

  Set sTB = Nothing
  Set oPic = Nothing
  Set ashp = Nothing
  DelTmp sFile
End Sub

Function GetWinTemp()
    Dim fs As Object
    Set fs = CreateObject("Scripting.FileSystemObject")
    GetWinTemp = fs.GetSpecialFolder(2)
    Set fs = Nothing
End Function

Function DelTmp(file As String)
    Dim fs As Object
    Set fs = CreateObject("Scripting.FileSystemObject")
    If fs.FileExists(file) Then
        fs.DeleteFile file, True
    End If
    Set fs = Nothing
End Function

In Module2:
Code:
'http://www.oaltd.co.uk/Excel/Default.htm, from PastePicture.zip:
'***************************************************************************
'*
'* MODULE NAME:     Paste Picture
'* AUTHOR & DATE:   STEPHEN BULLEN, Office Automation Ltd
'*                  15 November 1998
'*
'* CONTACT:         Stephen@oaltd.co.uk
'* WEB SITE:        http://www.oaltd.co.uk
'*
'* DESCRIPTION:     Creates a standard Picture object from whatever is on the clipboard.
'*                  This object can then be assigned to (for example) and Image control
'*                  on a userform.  The PastePicture function takes an optional argument of
'*                  the picture type - xlBitmap or xlPicture.
'*
'*                  The code requires a reference to the "OLE Automation" type library
'*
'*                  The code in this module has been derived from a number of sources
'*                  discovered on MSDN.
'*
'*                  To use it, just copy this module into your project, then you can use:
'*                      Set Image1.Picture = PastePicture(xlPicture)
'*                  to paste a picture of whatever is on the clipboard into a standard image control.
'*
'* PROCEDURES:
'*   PastePicture   The entry point for the routine
'*   CreatePicture  Private function to convert a bitmap or metafile handle to an OLE reference
'*   fnOLEError     Get the error text for an OLE error code
'***************************************************************************

Option Explicit
Option Compare Text

''' User-Defined Types for API Calls

'Declare a UDT to store a GUID for the IPicture OLE Interface
Private Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7) As Byte
End Type

'Declare a UDT to store the bitmap information
Private Type uPicDesc
    Size As Long
    Type As Long
    hPic As Long
    hPal As Long
End Type

'''Windows API Function Declarations

'Does the clipboard contain a bitmap/metafile?
Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long

'Open the clipboard to read
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long

'Get a pointer to the bitmap/metafile
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long

'Close the clipboard
Private Declare Function CloseClipboard Lib "user32" () As Long

'Convert the handle into an OLE IPicture interface.
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long

'Create our own copy of the metafile, so it doesn't get wiped out by subsequent clipboard updates.
Declare Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As Long, ByVal lpszFile As String) As Long

'Create our own copy of the bitmap, so it doesn't get wiped out by subsequent clipboard updates.
Declare Function CopyImage Lib "user32" (ByVal handle As Long, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long

'The API format types we're interested in
Const CF_BITMAP = 2
Const CF_PALETTE = 9
Const CF_ENHMETAFILE = 14
Const IMAGE_BITMAP = 0
Const LR_COPYRETURNORG = &H4

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Subroutine: PastePicture
'''
''' Purpose:    Get a Picture object showing whatever's on the clipboard.
'''
''' Arguments:  lXlPicType - The type of picture to create.  Can be one of:
'''                          xlPicture to create a metafile (default)
'''                          xlBitmap to create a bitmap
'''
''' Date        Developer           Action
''' --------------------------------------------------------------------------
''' 30 Oct 98   Stephen Bullen      Created
''' 15 Nov 98   Stephen Bullen      Updated to create our own copies of the clipboard images
'''

Function PastePicture(Optional lXlPicType As Long = xlPicture) As IPicture

'Some pointers
Dim h As Long, hPicAvail As Long, hPtr As Long, hPal As Long, lPicType As Long, hCopy As Long

'Convert the type of picture requested from the xl constant to the API constant
lPicType = IIf(lXlPicType = xlBitmap, CF_BITMAP, CF_ENHMETAFILE)

'Check if the clipboard contains the required format
hPicAvail = IsClipboardFormatAvailable(lPicType)

If hPicAvail <> 0 Then
    'Get access to the clipboard
    h = OpenClipboard(0&)

    If h > 0 Then
        'Get a handle to the image data
        hPtr = GetClipboardData(lPicType)

        'Create our own copy of the image on the clipboard, in the appropriate format.
        If lPicType = CF_BITMAP Then
            hCopy = CopyImage(hPtr, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)
        Else
            hCopy = CopyEnhMetaFile(hPtr, vbNullString)
        End If

        'Release the clipboard to other programs
        h = CloseClipboard

        'If we got a handle to the image, convert it into a Picture object and return it
        If hPtr <> 0 Then Set PastePicture = CreatePicture(hCopy, 0, lPicType)
    End If
End If

End Function


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Subroutine: CreatePicture
'''
''' Purpose:    Converts a image (and palette) handle into a Picture object.
'''
'''             Requires a reference to the "OLE Automation" type library
'''
''' Arguments:  None
'''
''' Date        Developer           Action
''' --------------------------------------------------------------------------
''' 30 Oct 98  Stephen Bullen      Created
'''

Private Function CreatePicture(ByVal hPic As Long, ByVal hPal As Long, ByVal lPicType) As IPicture

' IPicture requires a reference to "OLE Automation"
Dim r As Long, uPicInfo As uPicDesc, IID_IDispatch As GUID, IPic As IPicture

'OLE Picture types
Const PICTYPE_BITMAP = 1
Const PICTYPE_ENHMETAFILE = 4

' Create the Interface GUID (for the IPicture interface)
With IID_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

' Fill uPicInfo with necessary parts.
With uPicInfo
    .Size = Len(uPicInfo)                                                   ' Length of structure.
    .Type = IIf(lPicType = CF_BITMAP, PICTYPE_BITMAP, PICTYPE_ENHMETAFILE)  ' Type of Picture
    .hPic = hPic                                                            ' Handle to image.
    .hPal = IIf(lPicType = CF_BITMAP, hPal, 0)                              ' Handle to palette (if bitmap).
End With

' Create the Picture object.
r = OleCreatePictureIndirect(uPicInfo, IID_IDispatch, True, IPic)

' If an error occured, show the description
If r <> 0 Then Debug.Print "Create Picture: " & fnOLEError(r)

' Return the new Picture object.
Set CreatePicture = IPic

End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Subroutine: fnOLEError
'''
''' Purpose:    Gets the message text for standard OLE errors
'''
''' Arguments:  None
'''
''' Date        Developer           Action
''' --------------------------------------------------------------------------
''' 30 Oct 98   Stephen Bullen      Created
'''

Private Function fnOLEError(lErrNum As Long) As String

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

Select Case lErrNum
Case E_ABORT
    fnOLEError = " Aborted"
Case E_ACCESSDENIED
    fnOLEError = " Access Denied"
Case E_FAIL
    fnOLEError = " General Failure"
Case E_HANDLE
    fnOLEError = " Bad/Missing Handle"
Case E_INVALIDARG
    fnOLEError = " Invalid Argument"
Case E_NOINTERFACE
    fnOLEError = " No Interface"
Case E_NOTIMPL
    fnOLEError = " Not Implemented"
Case E_OUTOFMEMORY
    fnOLEError = " Out of Memory"
Case E_POINTER
    fnOLEError = " Invalid Pointer"
Case E_UNEXPECTED
    fnOLEError = " Unknown Error"
Case S_OK
    fnOLEError = " Success!"
End Select

End Function
 
Upvote 0
Would it be possible to alter the following code to allow filling a text box with an image (screenshot) in the clipboard?
HTML:
Private Sub CommandButton1_Click()

    Dim CB As New DataObject
        
        On Error Resume Next
            CB.GetFromClipboard
            Me.TextBox1.Value = CB.GetText
            
            If Err Then MsgBox "The clipboard contains No Text.": Err.Clear
        On Error GoTo 0
        
End Sub
 
Upvote 0

Forum statistics

Threads
1,214,819
Messages
6,121,729
Members
449,049
Latest member
MiguekHeka

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top