VBA: Returning the index of a formfield?

How do I return the index of a selected formfield in VBA?
SteveWAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

NoggyCommented:
Selection.FormFields(i).Name will return the name of the i-th Form Field in the selection (relative to the selection too - and not the document).

I presume that you will want the index of the Form Field with respect to the start of the document?
NoggyCommented:
SteveW, here's a little function that I knocked up for you. It will return the index number of the FIRST form field that it finds in a range (relative to the start of the document). If there are no form fields, it will return 0.

Public Function FormFieldIndex(ByVal rng As Range) As Long
    Dim fldName As String
    Dim lCount As Long
   
    With rng
        If .FormFields.Count = 0 Then
            FormFieldIndex = 0
            Exit Function
        End If
   
        fldName = .FormFields(1).Name
    End With
     
    With ThisDocument
        For lCount = 1 To .FormFields.Count
            If .FormFields(lCount).Name = fldName Then
                FormFieldIndex = lCount
                Exit Function
            End If
        Next lCount
    End With
End Function

So, to use it with a Selection class, you will need to call the function in your VB code with: FormFieldIndex(Selection.Range)
tureCommented:
SteveW,

This code shows the name and index of the currently selected form field. I had to use a loop to run through all FormFields, because I found no 'ActiveFormField' or similar way to determine which field is currently selected.

Sub ShowIndexAndNameOfSelectedFormField()
  Dim lngSelStart As Long
  Dim lngSelEnd As Long
  Dim lngIndex As Long
  Dim ff As FormField
 
  lngSelStart = Selection.Start
  lngSelEnd = Selection.End
 
  For lngIndex = 1 To ActiveDocument.FormFields.Count
    Set ff = ActiveDocument.FormFields(lngIndex)
    If ff.Range.Start <= lngSelStart And ff.Range.End >= lngSelEnd Then
      MsgBox Title:="Index", Prompt:=lngIndex
      MsgBox Title:="Name", Prompt:=ff.Name
    End If
  Next lngIndex
End Sub

Ture Magnusson
Karlstad, Sweden

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

NoggyCommented:
Ture - He, he :-) I beat you to it this time....
tureCommented:
Noggy...
Yes, you were quicker :0(
But not better :o)

Your function will not return the index number of the currently selected form field.

If I set the 'Run macro on entry' for the form fields to 'Test' (which uses your function), it will always return 0.
If I set 'Run macro on entry' to my procedure (ShowIndex), it will correctly show the index of the form field when the cursor moves to it.

Sub Test()
  MsgBox FormFieldIndex(Selection.Range)
End Sub

Public Function FormFieldIndex(ByVal rng As Range) As Long
    Dim fldName As String
    Dim lCount As Long
     
    With rng
        If .FormFields.Count = 0 Then
            FormFieldIndex = 0
            Exit Function
        End If
     
        fldName = .FormFields(1).Name
    End With
       
    With ThisDocument
        For lCount = 1 To .FormFields.Count
            If .FormFields(lCount).Name = fldName Then
                FormFieldIndex = lCount
                Exit Function
            End If
        Next lCount
    End With
End Function


Sub ShowIndex()
  Dim lngSelStart As Long
  Dim lngSelEnd As Long
  Dim lngIndex As Long
  Dim ff As FormField
   
  lngSelStart = Selection.Start
  lngSelEnd = Selection.End
 
  For lngIndex = 1 To ActiveDocument.FormFields.Count
    Set ff = ActiveDocument.FormFields(lngIndex)
    If ff.Range.Start <= lngSelStart And ff.Range.End >= lngSelEnd Then
      MsgBox Title:="Index", Prompt:=lngIndex
    End If
  Next lngIndex
End Sub

/Ture
tureCommented:
SteveW,
Please don't forget to grade this question or ask again if the posted suggestions didn't help.
/Ture
NoggyCommented:
Ture - Aaah, I was assuming that the complete field would be in the selection. Yours indeed is a bit better than mine in that you can have the selection as only part of the form field. It all depends on what SteveW means by "selected formfield" in his q.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Office

From novice to tech pro — start learning today.