PDA

View Full Version : Solved: Inserting text Form Fields into a table.



sallo
05-26-2005, 11:33 AM
Greetings,



I have a simple table setup. Two columns and it starts with three rows. In the last row I have inserted Text Form Fields into each column. When you tab out of the last field it will automatically create a new row.



What I am trying to do is when the new row is created, is to have Text Form Fields created in each column of the new row. And I am very close, but I am missing something, somewhere.



I have this code:



Private Sub Document_New()

Dim myTable As Table
Dim myRow As Row
Dim ColNum As Long

If Not Selection.Information(wdWithInTable) Then
Exit Sub ' no table; don't do any more
End If

' make an onject that represents the table
Set myTable = Selection.Tables(1)

' add a row to the bottom of the table
' and make an object that represents the row
Set myRow = myTable.Rows.Add

' use a loop to insert a form field into
' each cell in the new row
Selection.MoveRight Unit:=wdCell
For ColNum = 1 To myTable.Columns.Count
ActiveDocument.FormFields.Add _
Range:=myRow.Cells(ColNum).Range, _
Type:=wdFieldFormTextInput
Next ColNum

' clean up
Set myRow = Nothing
Set myTable = Nothing



End Sub



This code for the most part works. It will create a new row with the Text Fields just as I want it to. Unfortunately, I have to run it manually. What I want it to do, is when I tab out of the last filed, is execute and create the new row with the fields.



Any suggestions are appreciated.



Sallo

fumei
05-26-2005, 12:46 PM
Make the code fire as the OnExit macro for the last formfield.

Caveats:

1. record a macro that creates a formfield. In that you will see how to set a name. it is ALWAYS a good idea to explicitly name formfields.

2. you will also see how to set the OnExit macro. Obviously you will want the NEW last formfield to fire the same macro. So you want to make sure you remove the on exit macro from the (old) last formfield, and set it for the NEW last formfield.

MOS MASTER
05-26-2005, 02:45 PM
Hi And Welcome to VBAX! :hi:

What you want is possible but really not easy. (Had to use my brains on this one) :rofl:

To fully automate the process I'm using Application Event:
"App_WindowSelectionChange"

Yepz this is gonna slow things down a minor bit...but when you use Word in a normal fashion you're not going to notice this.

Ok I've made an example of how to use these application events.

The main code is in a classmodule called: "AppEvents"

Option Explicit

Public WithEvents App As Application

Private Sub App_WindowSelectionChange(ByVal Sel As Selection)
Dim iActiveColumn As Integer, iColumnCount As Integer
Dim iActiveRow As Integer, iRowCount As Integer
Dim oTable As Word.Table, oRow As Word.Row, oRange As Word.Range
Dim iCol As Integer

iActiveColumn = Selection.Information(wdEndOfRangeColumnNumber)
iColumnCount = Selection.Information(wdMaximumNumberOfColumns)
iActiveRow = Selection.Information(wdEndOfRangeRowNumber)
iRowCount = Selection.Information(wdMaximumNumberOfRows)

If iActiveColumn < iColumnCount Or _
iActiveRow < iRowCount Then
'Not in the last cell so do normal move
'Don't do anything
Else
'Yepz in the last cell
ActiveDocument.Unprotect Password:="MOS MASTER"
Set oTable = Sel.Tables(1)
Set oRow = oTable.Rows.Add

For iCol = 1 To oTable.Columns.Count
Set oRange = ActiveDocument.Range _
(oRow.Cells(iCol).Range.Start, oRow.Cells(iCol).Range.End)

oRange.FormFields.Add Range:=oRange, Type:=wdFieldFormTextInput
Next

ActiveDocument.Protect _
Type:=wdAllowOnlyFormFields, _
NoReset:=True, _
Password:="MOS MASTER"
End If

Set oRange = Nothing
Set oRow = Nothing
Set oTable = Nothing
End Sub


Then in the ClassModule ThisDocument the code to initialize the Class:

Option Explicit
Dim DoAppEvents As New AppEvents

Private Sub Document_Open()
Set DoAppEvents.App = Application
End Sub


Minor Cave-At though....You haven't mentioned your Word version.

As I recall well this Application Event came available in Word 2000 (or was it 2002)...Oh well for sure if you have '97 you're out of luck! :rofl:

Enjoy! :whistle:

sallo
05-27-2005, 10:14 AM
Works like a champ.

For what I thought was going to be a simple task, turned out to be pretty complex.

Thanks for all your help.

Sallo

MOS MASTER
05-27-2005, 10:29 AM
Hi Sallo,
Great! You're Welcome! :beerchug:

And yes if it has to do something realtime it's ussualy complex and you'll need some kind of event (Hard to understand for those, just starting to code) to make it happen..

Later...:whistle:

fumei
05-27-2005, 02:15 PM
No offence Jppst, but this is far more complicated than is needed.
Dim intCol As Long
Dim intRow As Long
Dim aCell As Cell
Dim var
If Selection.Information(wdWithInTable) = True Then
intCol = Selection.Tables(1).Columns.Count
intRow = Selection.Tables(1).Rows.Count
Else
MsgBox "Not in a table"
Exit Sub
End If
Set aCell = Selection.Tables(1).Cell(intRow, intCol)
aCell.Select
With Selection
.Collapse direction:=wdCollapseEnd
' makes new row
.MoveRight Unit:=wdCell
' make formfields to column count less one
' moving selection each time
For var = 1 To intCol - 1
.FormFields.Add Range:=Selection.Range, Type:= _
wdFieldFormTextInput
.MoveRight Unit:=wdCell
Next
' make the last formfield in the last column
.FormFields.Add Range:=Selection.Range, Type:= _
wdFieldFormTextInput
End With
End Sub

will put text formfields in a newly created row, regardless of the number of columns. You don't need the AppEvents, you don't need to figure out if the selection is in the last cell or not....you simply PUT IT in the last cell, and press Tab. Pressing Tab in the last cell has the VBA code equivalent of Selection.MoveRight Unit:=wdCell.

MOS MASTER
05-28-2005, 09:32 AM
No offence Jppst, but this is far more complicated than is needed.

Hi Gerry, :yes

None taken...but.

Your code doesn't do the same thing my code does!
The question was to dymically add formfields when one enters the last cell in the table so people can go on filling in the newly created formfields.

Your code doesn't take in account the fact the document should be protected because you can't use the fields in a non protected form. (Yes you no this but this is neccessary for this question so..) :rofl:

Also your code always creates the new formfields and mine only if you're in the last cell!

Also it has to be done dynamically so yes you DO need the application event. Or like you said before set an on exit macro to the last formfield. (And yes your macro could be added to that if you provide code for setting the on exit macro to the new last cell and you unset and set the document protection)

I do agree on you we could slimmer my code down abit. There's some leftover code from experimented that could be shrunk down. But it was my last post of that day and didn't have time to strip it so post it as is. (Has nothing do to with functionality BTW)

To sum it all up: We've both created workable code but the critters are doing entirely different things!

So is one better than the other...Dunno...:dunno

The Op is happy...therefore I'm happy! :whistle: