FIX: "Invalid function argument value, type, or count" Error

ID: Q129628

2.6x WINDOWS

The information in this article applies to:

SYMPTOMS

When the SCREEN WIZARD has been used to create a screen for two or more related tables, clicking the LOCATE button can produce this error message:

   Invalid function argument value, type, or count.

CAUSE

In the LOC_DLOG procedure for the LOCATE button, OBJVAR is used to provide the name of the memory variable, array element, or field associated with an object. However, OBJVAR is returning a NULL value rather than a CHARACTER value during a READ, which causes the error message.

RESOLUTION

NOTE: In Visual FoxPro, the One-To-Many Form Wizard is used for related tables. The One-To-Many Wizard does not have this problem.

To avoid this message, perform one of the following resolutions.

Resolution 1

Change the following line of code in the .SPR from

   DO WHILE !EMPTY(OBJVAR(m.i))

to the following:

   DO WHILE TYPE("OBJVAR(m.i)") = "C"

By checking the return type of the function, the error will not occur, and the loop will not continue, which is the purpose of checking EMPTY().

Resolution 2

Change the LOC_DLOG procedure in the .SPR file.

You can have the BROWSE window that is executed in the LOCATE button display all fields from the parent table or display only the fields included in the screen. For example, a screen may have been created that holds only the CNO and COMPANY fields from the CUSTOMER table; in this case, the BROWSE should display only the fields CNO and COMPANY, not all fields from CUSTOMER.

How to Display all Fields from a Table in the BROWSE:

1. Add the following to the SETUP code prior to #REGION 0:

   PUBLIC myprog
   myprog=PROGRAM()        && Store name of the screen currently running.
   mypath=FULLPATH(myprog) && Store the full path of the screen.

2. Replace the existing LOC_DLOG PROCEDURE in the CLEANUP code of the .SCX
   file with this code:

   PROCEDURE loc_dlog
      PRIVATE gfields,i
      DEFINE WINDOW wzlocate FROM 1,1 TO 20,40;
         SYSTEM GROW CLOSE ZOOM FLOAT FONT "MS Sans Serif",8
      MOVE WINDOW wzlocate CENTER
      ** Save the name of the currently used table:
      cur_tbl=ALIAS()
      ** Get the full path of where the .SCX table for this screen is:
      myscx= ;
      SUBSTR(FULLPATH(myprog+'.spr'),1,ATC('.',FULLPATH(myprog+'.spr'))-1)
      ** If the screen table isn't open, open it:
      IF !USED(myscx+'.scx')
         SELECT 0
         USE (myscx)+'.scx' AGAIN
      ELSE
         SELECT (myscx)+'.scx'
      ENDIF

      ** Get all name fields where objtype=15 and objcode=1
      ** objtype = 15 and objcode = 1 are the field names used
      ** in the screen
      COUNT FOR objtype=15 AND objcode=1 TO mnum
      ** Create an array to hold the field names used in the screen:
      DIMENSION test[mnum]
      j = 1
      ** Select the main, original table:
      SELECT (cur_tbl)
      m.gfields=SET('FIELDS',2)
      IF !EMPTY(RELATION(1))
         SET FIELDS ON
         IF m.gfields # 'GLOBAL'
            SET FIELDS GLOBAL
         ENDIF

         IF EMPTY(FLDLIST())
            m.i=1
            ** Select the screen's database:
            SELECT (myprog)
            SET FIELDS TO
            SET FILTER TO objtype=15 AND objcode=1
            GO TOP
            ** Grab the field names and place into array:
            * NOTE: If all the field objects are changed to memory
            * variables, this DO WHILE loop will go into an infinite loop.
            * SKIP only occurs when the entry is NOT a memory variable.
            * Also, if m.memvar is used, the "M." will not match it.
            DO WHILE !EOF()
            FOR j = 1 TO mnum
               IF ATC('M.',MLINE(name,1))=0
                  test[j]=MLINE(name,1)
                  SKIP
               ENDIF
            NEXT
            ENDDO
            SET FILTER TO
            SELECT (cur_tbl)
            SET FIELDS ON
            SET FIELDS GLOBAL
            j = 1
            FOR j = 1 TO mnum
               SET FIELDS TO (test[j])
            NEXT
         ENDIF
      ENDIF

      ** Close the screen file that was used:
      IF USED(myprog)
         SELECT (myprog)
         USE
         SELECT (cur_tbl)
      ENDIF

   BROWSE WINDOW wzlocate NOEDIT NODELETE ;
      NOMENU TITLE C_BRTITLE
      SET FIELDS &gfields
      SET FIELDS OFF
      RELEASE WINDOW wzlocate
      RELEASE test    && Release the array from memory.
   RETURN

How to Display Only the Fields Included in the Screen in the BROWSE:

1. Add the following code to the SETUP code prior to #REGION 0:

   PUBLIC myprog
   myprog=PROGRAM()        && Store name of the screen currently running.
   mypath=FULLPATH(myprog) && Store the full path of the screen.

2. Replace the existing LOC_DLOG PROCEDURE in the CLEANUP code of the .SCX
   file with this code:

   PROCEDURE loc_dlog
      PRIVATE gfields,i
      DEFINE WINDOW wzlocate FROM 1,1 TO 20,40;
         SYSTEM GROW CLOSE ZOOM FLOAT FONT "MS Sans Serif",8
      MOVE WINDOW wzlocate CENTER
      cur_tbl=ALIAS()
      myscx ;
      =SUBSTR(FULLPATH(myprog+'.spr'),1,ATC('.',FULLPATH(myprog+'.spr'))-1)
      IF !USED(myscx+'.scx')
         SELECT 0
         USE (myscx)+'.scx' AGAIN
      ELSE
         SELECT (myscx)+'.scx'
      ENDIF

      SET FILTER TO objtype=2
      GO TOP
      ** Get all expr fields where objtype=2:
      COUNT FOR objtype=2 TO mnum
      GO TOP
      curr_dbf = LEFT(MLINE(name,1),ATC('.dbf',MLINE(name,1))-1)
      SELECT (curr_dbf)
      num_flds1=FCOUNT()

      SELECT (cur_tbl)

      m.gfields=SET('FIELDS',2)
      IF !EMPTY(RELATION(1))
         SET FIELDS ON
         IF m.gfields # 'GLOBAL'
            SET FIELDS GLOBAL
         ENDIF

         IF EMPTY(FLDLIST())
            m.i=1
            FOR k = 1 TO fcount()
               SET FIELDS TO (FIELD(k))
            NEXT
         ENDIF
      ENDIF

      ** Close the screen file that was used:
      IF USED(myprog)
         SELECT (myprog)
         USE
         SELECT (cur_tbl)
      ENDIF

      BROWSE WINDOW wzlocate NOEDIT NODELETE ;
         NOMENU TITLE C_BRTITLE
      SET FIELDS &gfields
      SET FIELDS OFF
      RELEASE WINDOW wzlocate
   RETURN

STATUS

Microsoft has confirmed this to be a problem in the Microsoft products listed at the beginning of this article. This problem was corrected in Visual FoxPro 3.0 for Windows.

MORE INFORMATION

Steps to Reproduce Problem

1. Enter these commands:

   SELECT 0
   USE tutorial\customer
   SELECT 0
   USE tutorial\invoices
   INDEX ON cno TAG cno
   SET ORDER TO TAG cno
   SELECT customer
   SET RELATION TO cno INTO invoices
   SET SKIP TO invoices

2. Choose Wizard from the Run menu, and select Screen.

3. Add all fields from both tables. Select all the remaining defaults. Save

   as OBJVAR.

4. Enter this command:

   DO objvar.spr

5. As soon as the screen appears, click the LOCATE button. At this point,
   you'll see the error message:

   Invalid function argument value, type, or count.

Additional reference words: VFoxWin FoxWin 2.60 2.60a fixlist3.00 buglist2.60 buglist2.60a KBCategory: KBSubcategory: FxtoolWizscreen
Keywords          : kbcode FxtoolWizscreen 
Version           : 2.6x
Platform          : WINDOWS
Solution Type     : kbfix

Last Reviewed: May 22, 1998