Link to home
Create AccountLog in
Avatar of Bright01
Bright01Flag for United States of America

asked on

A Table within a User Form

EE Pros,

I have a requirement for a table of "attendees" to an event, that needs to be hidden except when called for.  My thought on this was, "can I embed a Table in a User Form and then access and hide the form upon required use?"  I have attached a WB.XLS as a mock up design (simple) to see if it is doable.  If not, I'll need other ideas but for now, this seems to be an approach worthy of investigating.  You will see that Sheet 1 has the Table.  And the UserForm is already identified in the VBA Editor.  What I don't know is how to marry the two together.

Any help would be appreciated.  Thank you in advance.

Avatar of Norie

If you had a listbox control on the userform you could populate it with data from the table like this.
With ListBox1
    .ColumCount = 6
    With Sheets("Attendees")
         .List = .Range("B8", .Range("G" & Rows.Count).End(xlUp)).Value
     End With 
End With

Open in new window

Avatar of Bright01


Norie,  Thanks for the quick reply.  I'm not trying to populate a listbox in a form from a table.  I'm trying to actually input the data into a Table that's within a Form.  In other words, when a Macro is triggered, up comes the Form that contains the Table (otherwise hidden).  Then you add several records / rows of information in and then close the form.

Does that make sense?


Option to insert your table as an image into your UserForm:
Step 1
Add the following code to your UserForm:
Private Sub okButton_Click()
Unload Me
MsgBox "Thank You"
End Sub

Private Sub UserForm_Initialize()

Dim ws As Worksheet
Dim img As MSForms.Image

Set ws = Sheets("Attendees")

FileName = Left(ThisWorkbook.FullName, Len(ThisWorkbook.FullName) - Len(ThisWorkbook.Name)) & "MyBitmap.bmp"
SaveClip2Bit FileName

Set img = Me.Controls.Add("Forms.Image.1", "TableImage", True)
img.Picture = LoadPicture(FileName)
img.Width = Me.Width
img.PictureSizeMode = fmPictureSizeModeStretch

End Sub

Private Sub UserForm_Terminate()

If FileName <> "" Then Kill FileName

End Sub

Open in new window

Step 2
Add a module with the following code adapted from answer #6 here
'* MODULE NAME: Paste Picture
'* AUTHOR & DATE: STEPHEN BULLEN, Office Automation Ltd
'* 15 November 1998
'* 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.
'* 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

''' 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

Public Sub SaveClip2Bit(FileName As String)
    On Error Resume Next
    'SavePicture PastePicture, Application.GetSaveAsFilename("MyBitmap.bmp", "Bitmap Files (*.bmp), *.bmp")
    SavePicture PastePicture, FileName
End Sub

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)
            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

' 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 S_OK = &H0

Select Case lErrNum
    fnOLEError = " Aborted"
    fnOLEError = " Access Denied"
    fnOLEError = " General Failure"
    fnOLEError = " Bad/Missing Handle"
    fnOLEError = " Invalid Argument"
    fnOLEError = " No Interface"
    fnOLEError = " Not Implemented"
    fnOLEError = " Out of Memory"
    fnOLEError = " Invalid Pointer"
    fnOLEError = " Unknown Error"
Case S_OK
    fnOLEError = " Success!"
End Select

End Function

Open in new window

Your table will be inserted as an image into your UserForm. You can change the size of the image as necessary to fit your needs.

Note - This saves the image to the folder where the workbook is saved. It then deletes the image file when the UserForm is closed. If you want the user to select where to save the image, replace this line:
SavePicture PastePicture, FileName

Open in new window

With this line:
SavePicture PastePicture, Application.GetSaveAsFilename("MyBitmap.bmp", "Bitmap Files (*.bmp), *.bmp")

Open in new window

Source is from
here, I just tweaked it as per your requirement.
Please find attached for your reference. You'll probably want to make some other changes to the code then as well.
I also know, this is not what you want, but this will give you an idea, you cannot load Table on UserForm but you can transform your table image to UserForm for presentation.
I have no idea what this refers to.  I'm not trying to post/paste an image, I'm trying to embed a Table in a Form so I can call up the form from a Worksheet and input data directly into the table that is within the form.

I don't think the recommendation above does that.  It appears to be an approach to take data from a Table and post it as an image to a Form.

Sorry for misunderstanding! I will be back shortly with another approach
No worries...Thank you for the assistance.
What exactly do you mean by a 'table'?

If you mean a ListObject on a sheet then as far as I'm aware there's no way to embed such an object on a userform.
Please find attached...

Click on Add Entry To Table, UserForm will pop up to enter details, once you fill all the details press Add Record, it will prompt you, one record successfully added, do you wanna add new record, if you press Yes, it will pop UserForm again and you can enter another detail, if you press No, it will close the form. All the records will be added to the last row of your table.

Hope this help!
As you are using a Table then Norie's suggestion makes sense. I'll post an example for you incorporating adding entries
This code would populate the listbox directly from the table.
Option Explicit
Dim lst As ListObject

Private Sub UserForm_Initialize()

    Set lst = Sheets("Attendees").ListObjects("Table1")
    With Me.ListBox1
        .ColumnCount = lst.ListColumns.Count
        .ColumnHeads = True
        .RowSource = lst.DataBodyRange.Address(External:=True)
    End With
End Sub

Open in new window

Again, I'm not clear on this.  If we use a Listbox, where is the Table?  Outside the List box?  And are we still using a Form?  In the original ask here, the Table would be INSIDE the form.  The form would be called up, data would be entered into the table and then the form would again be hidden.

A simple example would be most helpful.

This example displays the data in a ListBox and controls to add new entries.

It works using the Table and the displayed data is updated in the ListBox automatically.

It is written to be easy to maintain so that if necessary new columns and textboxes cabn be added with minimum effort

It would be a simple step to allow deleting of selected records. I can help you with this if you want, but I'm finishing now. I'll be pleased to help tomorrow.
I don't think I'm explaining this right.  Roy, the example you are demonstrating is a Table with List boxes.  I get that.  What I can't seem to explain is that I am trying to have the Table appear and disappear so as to be "brought up" to put information in, and"retracted" to hide it.  I thought a creative way to do that was to use a USERFORM and embed a Table into it.  I'm getting the sense that no one has done that.  The reason I thought it would work, is I've used Userforms a lot for inputting data, just not in a table.

Have you tried my solution? using UserForm to update table?
Avatar of Roy Cox
Roy Cox
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
The code that I have used uses the ListObjects features to add data simply . I don't understand what you mean by hiding the Table. You cannot embed a Table on a UserForm. The ListBox represents the Table on the sheet.
Where is the code?  It's not in the Sheet, the Form or a module.

Link to home
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
If above solution is not what you want, then a possible solution might be which will display a userform for a table. Perhaps this is something you could use
Shums and Roy,

Thank you for your posts.  You both gave me good ideas.  I think Roy put it best when he said, "You cannot put a Table in a Form".  That means I'm going to have to look hard at both solutions you guys provided.

Again, thanks for the run-thru.

You're Welcome B.! Glad you understood, its not possible to embed table in UserForm.
Eh, I kind of mentioned that you couldn't 'embed'/'put' a table on a form.

PS I had a whole spiel, and a workbook ready to post earlier but since this is solved...
+1 Norie, but lovin Shums' & Roy's 'never say die' attitude!
Pleased to help