Forma usual de usar Scatter Name

3,060 views
Skip to first unread message

Analyzer

unread,
Jun 7, 2013, 4:59:37 PM6/7/13
to Comunidad de Visual Foxpro en Español

Si las propiedades correspondientes a nombres de campos no existen para el objeto, SCATTER...NAME ADDITIVE las crea automáticamente. Sin embargo, SCATTER podría no crear todas las propiedades necesarias ya que algunas podrían estar marcadas como Oculta o Protegidas. Si Visual FoxPro no puede crear o establecer una propiedad, genera un error. Por ejemplo, puede tener un nombre de campo que coincida con el nombre de una propiedad nativa de un objeto de Visual FoxPro siempre el cuando los tipos de datos sean los mismos, sin embargo, Visual FoxPro genera un error si el nombre del campo coincide con el nombre de un método, evento u objeto.

Puede evitar problemas utilizando un objeto creado por SCATTER...NAME y no uno derivado de una clase de Visual FoxPro. Distinto a lo que ocurre cuando SCATTER se usa con sólo NAME, Visual FoxPro no sobrescribe el objeto existente para crear un nuevo objeto.

SCATTER...NAME ADDITIVE no genera un error cuando una propiedad de sólo lectura no se puede establecer como el valor de un campo de la tabla. Sin embargo, el valor de la propiedad permanece sin cambiar.

El ejemplo que trae es:

CREATE TABLE Test FREE ;
(Object C(10), Color C(16), SqFt n(6,2))

SCATTER NAME oTest BLANK
oTest.Object="Box"
oTest.Color="Red"
oTest.SqFt=12.5

APPEND BLANK
GATHER NAME oTest
RELEASE oTest
BROWSE

Supongo que el append blank, gather name se puede cambiar por la sintaxis del insert into:

INSERT INTO dbf_name FROM FROM NAME ObjectName

Pero cuál es la forma "recomendada" de usar el scatter name para generar correctamente los nombres de propiedades del objeto y evitar los inconvenientes que menciona la ayuda?..

Saludos!

Fernando D. Bozzo

unread,
Jun 7, 2013, 5:59:42 PM6/7/13
to publice...@googlegroups.com
Hola Analyzer, no sufras, usando SCATTER NAME loRegistro nunca te va a pasar lo que dice ahi, ya que se crea un nuevo objeto basado en la clase EMPTY que no tiene propiedades ni métodos.

Seguramente eso se refiera a si usás objetos preexistentes basados en otra clase distinta, como por ejemplo custom, donde te daría problemas si tuvieras nombres de campos que coincidan con sus propiedades (height, width, parent, etc)
Y a lo último, sí, tu suposición es correcta.


Saludos.-

Analyzer

unread,
Jun 7, 2013, 7:54:24 PM6/7/13
to publice...@googlegroups.com
Maestro Bozzo,

Ya vi por ahi lo del SCATTER MEMO NAME loRegistro. Con eso grabaría también los campos memos.

Eso tambien forma parte de lo que deseo saber..  La sintaxis que mas usan en la práctica ( porque los manuales dicen muchas cosas que luego ni se usan por ser malas prácticas ).

¿Usan el blank y el adittive en la vida real?..

Tendrán un ejemplo sencillo de la vida real?..

Gracias!

Carlos Miguel FARIAS

unread,
Jun 8, 2013, 11:39:19 AM6/8/13
to Grupo Fox
El SCATTER es un comando interesante para transferir varios valores de una tabla a memoria.
Su contrapartida es el GATHER que pasa datos de memoria a la tabla.

SCATTER MEMVAR, en el viejo VFP, se usaba para definir en un solo comando, variables de memoria (m.variable), con igual nombre a los campos de la tabla (nativa), sobre los que se podía trabajar, sin afectar el registro en si (y por lo tanto, no crear sobre el mismo un lock implícito).
Luego de modificados los datos en memoria, los mismos se grababan en el registro con un GATHER MEMVAR

SCATTER MEMVAR BLANK, servía es igual que el anterior, pero las variables de memoria, en lugar de tener los datos de la fila, tenían valores "en blanco" y del mismo tipo.
El parámetro LIKE permite ser selectivo en cuanto a que campos recuperar, MEMO permitía además transferir campos memo (en los viejos equipos, eso afectaba el tiempo de respuesta, y se usaba si realmente se requería). ARRAY, permite pasar los datos a un arreglo, práctico si sobre todos los campos, se debe aplicar un proceso común y son muchos los campos.

Con VFP, se agrega la posibilidad de NAME, que es transferir los datos a un objeto no existente o existente.
Si no existe, se crea un objeto del tipo EMPTY, que no tienen métodos ni nada, solo propiedades.
Esto es práctico si luego quiere transferir todos esos datos a una función, solo tengo que transferir un objeto.

Si el objeto existe, usas ADDITIVE, por ejemplo
SCATTER NAME THISFORM ADDITIVE
Entonces, agrega al formulario los campos de la tabla con sus valores o reemplaza los valores de las propiedades si existen y tienen igual nombre.
Con BLANK, te agrega las propiedades con igual nombre que la tabla, con datos "en cero/blanco" si no existen.

Si trabajas con un motor de bd externo, podes usarlo contra el cursor que te retorna por ejemplo sqlexec-

Saludos: Miguel, La Pampa (RA)

Analyzer

unread,
Jun 8, 2013, 4:17:05 PM6/8/13
to Comunidad de Visual Foxpro en Español
CMF,

Sin palabras! La explicación fue muy completa y le agradezco infinitamente.

Por alguna razón me parece mucho mas entendible su aclaración, que la de la misma ayuda de VFP. Raro que la ayuda no traiga mas ejemplos..


Saludos!

Fernando D. Bozzo

unread,
Jun 8, 2013, 6:02:14 PM6/8/13
to publice...@googlegroups.com
No tengo nada que agregar, la explicación de Miguel fue Magistral.

Esteban Herrero

unread,
Jun 11, 2013, 10:13:57 PM6/11/13
to publice...@googlegroups.com

Miguel, muy buena tu explicación, muy clara…

 

Saludos.

 

Esteban

 

Juan Bosco

unread,
Oct 21, 2020, 4:13:14 PM10/21/20
to Comunidad de Visual Foxpro en Español
Miguel buen dia!! Ya tengo rato utilizando el scatter name; pero tengo la siguiente duda : ¿hay forma de mantener publicas las variables del name en todo el formulario??? Lo logro solo cuando el formulario es modal y declaro el scatter name fuera de la forma (desde un prg por ejemplo). Pero si lo hago dentro de un formulario modeless no funciona mas que en el evento que lo dispara. Estoy actualmente creando un objeto ligado al formulario; pero me parece que es muy engorroso

Saludos a todos y gracias de antemano

Edgar Acevedo

unread,
Oct 21, 2020, 5:52:15 PM10/21/20
to publicesvfoxpro
Saludos Juan:

Yo busqué por mucho tiempo lo que consultas a Miguel.  No lo encontré.  No se si por inútil o porque simplemente no hay forma directamente prevista por los diseñadores de VFP para hacerlo.  
Como en mi caso, la idea de un SCATTER así es para manipular fácilmente los campos de una tabla para su procesamiento y posterior resguardo de vuelta a la tabla, no tuve más opción que hacer una función que antes declarara "públicos" los nombres de variables correspondientes a campos de una tabla, y otra función para cuando no me conviniera que quedaran "publicos" y evitar futuras confusiones en cascada. 
Si de algo te sirve te las copio abajo (es código viejo, como del 2,002 o algo así...):


* Si quiero hacer un SCATTER para la tabla "Facturas", hago esto:
DO PubliVar WITH "Facturas", "NULL", .F.)
SELECT Facturas
SCATTER MEMVAR MEMO
.. (código)
.. (código)

* Y cuando ya no me sirve que éstas sean públicas...
DO ReleaVar WITH "Facturas"

PROCEDURE PubliVar
 * Esta subrutina declara como variables públicas los nombres de campo de una tabla:
 * PARÁMETROS:
 *   M.PubTab es la tabla cuyos campos se sacarán los nombres de campos para hacerlos públicos
 *   M.BubSca debe decir "DATA" si se leerán los contenidos de dichos campos
 *            decir "NULL" si solo se desea publicar los nombres, pero sin datos ni definiciones de tipo
 *   M.PubOpe Si este parámetro es .T. la tabla del parámetro M.PubTab se quedará abierta
 *            este parámetro es .F. la tabla del parámetro M.PubTab se cerrará luego de publicar sus datos   PARAMETERS M.PubTab, M.PubSca, M.PubOpe
   M.PubliDBF = ALIAS()
   M.LecPub = .F.
   IF TYPE("M.PubSca") = "U" OR TYPE("M.PubSca") = "L"
      M.PubSca = "NONE"
   ELSE
      IF (ALLTRIM(M.PubSca) $ "DATA-NULL") = .F.
         M.PubSca = "DATA"
      ENDIF
   ENDIF
   IF "." $ M.PubTab
      M.PubDBF = LEFT(M.PubTab, AT(".", M.PubTab) - 1)
   ELSE
      M.PubDBF = ALLTRIM(M.PubTab)
   ENDIF
   IF USED(M.PubDBF)
      SELECT (M.PubDBF)
      M.LecPub = .T.
   ELSE
      IF USED(UPPER(JUSTFNAME(M.PubTab)))
         SELECT (UPPER(JUSTFNAME(M.PubTab)))
         M.LecPub = .T.
      ELSE
         IF RIGHT(ALLTRIM(M.PubTab), 4) # ".DBF"
            M.PubTab = ALLTRIM(M.PubTab) + ".DBF"
         ENDIF
         IF FILE(M.PubTab)
            TRY
               IF M.PubOpe
                  USE (M.PubTab) IN 0 AGAIN SHARED
                  SELECT (UPPER(JUSTFNAME(M.PubTab)))
               ELSE
                  USE (M.PubTab) IN 0 AGAIN ALIAS "PubTab99" SHARED
                  SELECT PubTab99
               ENDIF
               M.LecPub = .T.
            CATCH
               M.LecPub = .F.
            ENDTRY
         ENDIF
      ENDIF
   ENDIF
   IF M.LecPub
      M.INSTRU = 'RELEASE '
      FOR N = 1 TO FCOUNT()
         M.INSTRU = M.INSTRU + 'M.' + ALLT(UPPER(FIELD(N))) + ', '
      ENDFOR
      M.INSTRU = LEFT(ALLT(M.INSTRU), LEN(ALLT(M.INSTRU)) - 1)
      &INSTRU
      M.INSTRU = STRTRAN(M.INSTRU, "RELEASE", "PUBLIC")
      &INSTRU
      DO CASE
         CASE UPPER(ALLTRIM(M.PubSca)) = "DATA"
            IF EOF()
               IF RECCOUNT() > 0
                  SKIP -1
               ENDIF
            ENDIF
            SCATTER MEMO MEMVAR            
         CASE UPPER(ALLTRIM(M.PubSca)) = "NULL"
            IF EOF()
               GO TOP
            ENDIF
            SCATTER MEMO BLANK MEMVAR
      ENDCASE
   ENDIF
   IF USED("PubTab99")
      USE IN PubTab99
   ENDIF
   IF USED(M.PubliDBF)
      SELECT (M.PubliDBF)
   ENDIF
RETURN

PROCEDURE ReleaVar
 * Esta subrutina libera de la memoria las variables públicas creadas a partir de los nombres de campo de la tabla
 * indicada en el parámetro M.PubTab
 * PARÁMETROS:
 *   M.PubTab es la tabla cuyos nombres de campo existen como variables públicas que serán liberadas de la memoria
   M.LecRel = .F.
   IF USED(M.RelTab)
      SELECT (M.RelTab)
      M.LecRel = .T.
   ELSE
      IF USED(UPPER(JUSTFNAME(M.RelTab)))
         SELECT (UPPER(JUSTFNAME(M.RelTab)))
         M.LecRel = .T.
      ELSE
         IF RIGHT(ALLTRIM(M.RelTab), 4) # ".DBF"
            M.RelTab = ALLTRIM(M.RelTab) + ".DBF"
         ENDIF
         IF FILE(M.RelTab)
            USE (M.RelTab) IN 0 AGAIN ALIAS "RelTab99"
            SELECT RelTab99
            M.LecRel = .T.
         ENDIF
      ENDIF
   ENDIF
   IF M.LecRel
      M.INSTRU = 'RELEASE '
      FOR N = 1 TO FCOUNT()
         M.INSTRU = M.INSTRU + 'M.' + ALLT(UPPER(FIELD(N)))+ ', '
      ENDFOR
      M.INSTRU = LEFT(ALLT(M.INSTRU), LEN(ALLT(M.INSTRU)) - 1)
      &INSTRU
   ENDIF
   IF USED("PubTab99")
      USE IN PubTab99
   ENDIF
RETURN





--
Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/c36efb47-ce91-4f3b-8f2e-c55c0a96240bn%40googlegroups.com.

Juan Bosco

unread,
Oct 21, 2020, 6:43:00 PM10/21/20
to Comunidad de Visual Foxpro en Español
Te agradezco mucho tu ayuda!! Voy a probar tu código.

Saludos

Luis Maria Guayan

unread,
Oct 23, 2020, 3:53:40 PM10/23/20
to Comunidad de Visual Foxpro en Español
Yo utilizo propiedades del formulario sin problemas. (creadas previamente)

SELECT (ThisForm.cAlias)
SCATTER BLANK NAME ThisForm.oReg

y no tengo ningún problema en ningún método del formulario.

 --

Luis María Guayán
Tucumán, Argentina
_______________________________


Comunidad Visual FoxPro en Español
http://comunidadvfp.blogspot.com

Reply all
Reply to author
Forward
0 new messages