Link to home
Start Free TrialLog 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.

B.
IntegrateListintoForm.xls
Avatar of Norie
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

ASKER

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?

B.
Hi,

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")
ws.ListObjects("Table1").Range.CopyPicture

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



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

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.
IntegrateListintoForm.xlsm
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.

B.
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!
IntegrateListintoForm_v1.xlsm
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.

B.
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.
IntegrateListintoForm.xls
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.

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

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.

B.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If above solution is not what you want, then a possible solution might be http://spreadsheetpage.com/index.php/dataform/home 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.

B.
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.

https://www.experts-exchange.com/questions/29009165/A-Table-within-a-User-Form.html?anchorAnswerId=42049503#a42049503

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