Thursday, September 8, 2011

An alternative method of adding a row to a protected table

The previous method created the new row in the table and added the fields to the cells. The following takes an alternative approach and copies the last row of the table, complete with its fields and associated macros, and pastes it at the end of the table. It then removes the on exit macro from what was previously the last row, so that there can be no false triggering of the macro if a user goes back to amend a field's content in the last column of a previous row.
The macro makes use of the wdDialogFormFieldOptions dialog, which has the following arguments: Entry, Exit, Name, Enable, TextType, TextWidth, TextDefault, TextFormat, CheckSize, CheckWidth, CheckDefault, Type, OwnHelp, HelpText, OwnStat, StatText, Calculate, to modify the field properties.
As executing this dialog box clears the user entered result of the field, if that content is later required, as seems probable, it is necessary to store the content and replace it after executing the dialog changes.
Sub AddRow()
'Run on exit from the last form field in
'the last row of the table

Dim oTable As Table
Dim oRng As Range
Dim oCell As Range
Dim oLastCell As Range
Dim sResult As String
Dim iRow As Long
Dim iCol As Long
Dim CurRow As Long
Dim i As Long
Dim sPassword as String
sPassword = "" 'password to protect/unprotect form
With ActiveDocument
     .Unprotect Password:=sPassword 'Unprotect document
     Set oTable = .Tables(1) 'Select the appropriate table
     iRow = oTable.Rows.Count 'Record the last row number
     iCol = oTable.Columns.Count 'Record the last column number
     Set oLastCell = oTable.Cell(iRow, iCol).Range 'Record the last cell
     sResult = oLastCell.FormFields(1).Result 'Get the value in the last cell
     Set oRng = oTable.Rows(iRow).Range 'Add the last row to a range
     oRng.Copy 'Copy the row
     oRng.Collapse wdCollapseEnd 'collapse the range to its end.
     oRng.Select 'the end of the table
     Selection.Paste 'Paste the row at the end of the table
     CurRow = iRow + 1 'Record the new last row
     For i = 1 To iCol 'Repeat for each column
          Set oCell = oTable.Cell(CurRow, i).Range 'process each cell in the row
          oCell.FormFields(1).Select 'Select the first field in the cell
          With Dialogs(wdDialogFormFieldOptions) 'and name it
               .name = "Col" & i & "Row" & CurRow 'eg Col1Row2
               .Execute 'apply the changes
          End With
     Next
i
     'Select the formfield in the last cell of the previous row
     oLastCell.FormFields(1).Select
     With Dialogs(wdDialogFormFieldOptions)
          .Exit = "" 'and remove the exit macro
          .Execute 'apply the changes
          'but note that this clears the value from the cell
     End With
     oLastCell.FormFields(1).Result = sResult 'so restore the result of the cell
     .Protect NoReset:=True, Password:=sPassword, _
     Type:=wdAllowOnlyFormFields 'Reprotect the form
     .FormFields("Col1Row" & CurRow).Select 'and select the next field to be completed
End With
End Sub

No comments:

Post a Comment