Hi Ahmed,
Your Userform is a good start -- it works, and it produces the desired table.
When you export a userform, Word creates the two files you mentioned, with .frm and .frx extensions. The .frm file is a text file that contains the VBA code of the form, plus a few properties such as its title, size, and screen location. The .frx file is a binary code file that contains the visible parts of the form -- the text boxes, buttons, and so on. When you ask to import a userform into the VBA editor, you need to have both files in the same folder. The Import dialog asks for only the .frm file, but it imports both files at the same time.
An important point about creating Userforms is that extra care should be taken to make them work the way most users come to expect from the way Microsoft's built-in dialog boxes work. Some of those properties are not obvious, so I'll point them out.
It's possible to display a userform with just the single line of code
UserForm2.Show
but that works well only for very simple userforms such as this one. Many userforms are intended to run many times in the same document, or they may start up other userforms, among other complications. A better policy is to run every userform from a macro in a separate module, with code like this:
Sub RunForm()
Dim dlg As UserForm2
Set dlg = New UserForm2
dlg.Show
Set dlg = Nothing
End Sub
Another thing about userforms is the difference between the Unload command and the Hide method. Unload tells VBA to remove the userform from memory, including its code. After the Unload command runs, no other code from inside the form can run. Many userforms pass data from their text boxes (or list boxes, etc.) to the macro that started the userform, but Unload won't let that happen. It's better to use the Hide method of the userform to make the form invisible, but leave the code running in the background. Control then returns to the macro (like RunForm), and the code is finally unloaded when the Set dlg = Nothing statement runs.
Since Hide is a method of the userform, the syntax is
Me.Hide
where "Me" refers to the running userform.
In the code below, you'll see that I put the Me.Hide statement at the end of the CommandButton1_Click procedure, instead of having Unload Me at the beginning. I also added the Trim function to the tests for empty text boxes, because a user is likely to press the space bar to get rid of a number in the box instead of using the Delete or Backspace key. The Trim function removes spaces from the start or end of strings, so this way the condition will be True if the box is completely empty or contains only one or more spaces.
It's often a good idea to supply text boxes with default values. Then, if the defaults are what the user wants, they need only click OK (or press Enter) to accept them. If they want some other values, they can overtype the defaults. To put the defaults in, you use the Userform_Initialize procedure. You can click the Userform item in the left-hand dropdown at the top of the macro editor's code window, and then select Initialize in the right-hand dropdown to insert the proper Sub and End Sub statements. Then fill in the procedure's code. You can see this in the code below.
One more suggestion: You should always rename modules, userforms, labels, and controls with names that indicate their purpose. For example, it would be useful in this userform to rename TextBox1 as tbxColumns and TextBox2 as tbxRows. The prefixes of the names are optional, but they are useful for avoiding bugs. In this case, "tbx" is an abbreviation of "textbox"; I use "cmd" for command buttons, "lbx" for list boxes, and so forth.
For more information about userforms, read some of the articles at https://wordmvp.com/FAQs/Userforms.htm .
Try the following code in your userform.
Private Sub CommandButton1_Click()
If Trim(TextBox1.Value) = "" Or Trim(TextBox2.Value) = "" Then
MsgBox "You did not enter the number of columns or the number of rows.", vbExclamation
Me.Hide
Exit Sub
End If
Dim oTable As Table
Set oTable = ActiveDocument.Tables.Add(Range:=Selection.Range, _
NumRows:=TextBox2.Value, NumColumns:=TextBox1.Value, AutoFitBehavior:=wdAutoFitFixed)
With oTable
'.Columns.Width = InchesToPoints(2)
.Borders.InsideLineStyle = wdLineStyleSingle
.Borders.OutsideLineStyle = wdLineStyleSingle
End With
Me.Hide
End Sub
Private Sub UserForm_Initialize()
TextBox1.Value = 2
TextBox2.Value = 1
' select the number in TextBox1
TextBox1.SelStart = 0
TextBox1.SelLength = 1
' make the Enter key "push" the OK button
CommandButton1.Default = True
End Sub