24 de septiembre de 2001

Generar un GUID

Obtiene un GUID en formato {nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}
*!* Obtiene un GUID en formato {nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}
*!* Sintaxis: GetGuid()
*!* Valor devuelto: lcGuid
FUNCTION GetGuid
  LOCAL lnCnt, lcGuid, lcData1, lcData2, lcData3, lcData4, lcData5
  *!* Instrucciones DECLARE DLL para manipular obtener un GUID
  DECLARE INTEGER CoCreateGuid IN Ole32.DLL STRING @lpGuid
  *!* Valores
  lnCnt   = 0
  lcGuid  = ""
  lcData1 = ""
  lcData2 = ""
  lcData3 = ""
  lcData4 = ""
  lcData5 = ""
  lpGuid  = REPLICATE(CHR(0), 17)
  *!* Obtener el GUID
  IF CoCreateGuid(@lpGuid) = 0
    *!* Valores
    *!* Los 8 primeros dígitos
    lcData1 = RIGHT(TRANSFORM(StrToLong(LEFT(lpGuid, 4)), "@0"), 8)
    *!* Los 4 segundos dígitos
    lcData2 = RIGHT(TRANSFORM(StrToLong(SUBSTR(lpGuid, 5, 2)), "@0"), 4)
    *!* Los 4 terceros dígitos
    lcData3 = RIGHT(TRANSFORM(StrToLong(SUBSTR(lpGuid, 7, 2)), "@0"), 4)
    *!* Los 4 cuartos digitos
    lcData4 = RIGHT(TRANSFORM(StrToLong(SUBSTR(lpGuid, 9, 1)), "@0"), 2);
      + RIGHT(TRANSFORM(StrToLong(SUBSTR(lpGuid, 10, 1)), "@0"), 2)
    lcData5 = ""
    *!* Los 12 digitos finales
    FOR lnCnt = 1 TO 6
      lcData5 = lcData5 + RIGHT(TRANSFORM(StrToLong(SUBSTR(lpGuid, 10 + lnCnt, 1))), 2)
    ENDFOR
    *!* Verifica la longitud de los 12 digitos finales. Si son menores de 12 es que el resto son 0
    IF LEN(lcData5) < 12
      lcData5 = lcData5 + REPLICATE("0", 12 - LEN(lcData5))
    ENDIF
    *!* Valores
    lcGuid = "{" + lcData1 + "-" + lcData2 + "-" + lcData3 + "-" + lcData4 + "-" + lcData5 + "}"
  ENDIF
  *!* Retorno
  RETURN lcGuid
ENDFUNC
*!* Convierte un 4-byte CHARACTER STRING a un LONG INTEGER
*!* Sintaxis: StrToLong(tcLongStr)
*!* Valor devuelto: lnRetval
*!* Argumentos: tcLongStr
*!* tcLongStr especifica el 4-byte character string a convertir
FUNCTION StrToLong
  LPARAMETERS tcLongStr
  LOCAL lnCnt, lnRetVal, lcLongStr
  *!* Valores
  lnRetVal  = 0
  lcLongStr = IIF(EMPTY(tcLongStr), "", tcLongStr)
  *!* Convertir
  FOR lnCnt = 0 TO 24 STEP 8
    lnRetVal  = lnRetVal + (ASC(lcLongStr) * (2^lnCnt))
    lcLongStr = RIGHT(lcLongStr, LEN(lcLongStr) - 1)
  NEXT
  *!* Retorno
  RETURN lnRetVal
ENDFUNC

21 de septiembre de 2001

Database Design for Mere Mortals

Titulo : Database Design for Mere Mortals : A Hands-On Guide to Relational Database Design
Autor : Michael Hernandez
ISBN : 0201694719
Editora: Addison-Wesley Pub Co
Nº Paginas: 480



Contenido :

1- ¿ Que es un banco de datos relacional ?
2- Objetivos del Proyecto
3- Terminologías
4- Visión Conceptual
5- Comenzando el Proceso
6- Analizando el Banco de Datos Existente
7- Estableciendo las estructuras de las tablas
8- Índices
9- Especificación de los campos
10- Relacionamientos entre las tablas
11- Reglas de Negocio
12- Vistas
13- Examinando la integridad de los Datos
14- Un Mal Proyecto . Que se debe hacer
15- Cometiéndose o Quebrando reglas

Comentario :

El autor explica en un lenguaje común (fácil de entender) como desarrollar cualquier Base de datos . Sin importar la tecnología de esa base de datos , ni el lenguaje (puede ser en Vfox , Access , MS SQL Server , etc) .

El autor muestra en el libro como iniciar un proyecto , como realizar la documentación del mismo , todo lo que se debe hacer antes de escribir la primer línea de código . Todo es mostrado con muchos ejemplos , bien detallado y creo que es una lectura obligatoria para todos lo que día a día trabajamos , modificamos y proyectamos bases de datos .

Cada vez que comienzo un nuevo proyecto , le doy una leída a los capítulos 5 , 6 y 7 . Y con eso me evito futuros dolores de cabeza por un mal diseño . El editor técnico del libro es Jim Booth .   Destaque: ' Los capítulos 5 y 6 , donde la atención del autor para los detalles es impresionante y las explicaciones del proceso de entrevista son imprescindibles para cualquier persona , incluyendo los proyectistas con experiencia en de bases de datos relacionales ' Palabras de Jim Booth en su opinión sobre el libro .

Observaciones: Yo en realidad tengo la versión en Portugués de este libro (ISBN 85-346-1089-4 Editora Makron Books) coloque la información del libro en ingles porque se que para muchos de uds es mas fácil leer libros en ingles que en portugués.

Mas Info: Aquí

Nivel : Inicial-Intermedio.

20 de septiembre de 2001

VFP 7: Los nuevos comandos, funciones y clases.

Nuevos comandos, funciones y clases de Visual FoxPro 7
Por: Pablo Roca

COMANDOS Y VARIABLES DE SISTEMA

_Codesense System Variable
Contiene el nombre de la aplicación que crea funciones de IntelliSense.

_OBJECTBROWSER System Variable
Contiene el nombre de la aplicación del browser del objeto.

_TASKLIST System Variable
Esta variable de sistema contiene el nombre del programa encargado de la lista de tareas.

_VSBUILD System Variable
Contiene el nombre de la aplicación de la estructura del proyecto del Visual Estudio

FUNCIONES

ADLLS( ) Function
Retorna un vector conteniendo el nombre de las DLLs cargadas.

ASESSIONS( ) Function
Retorna el número de sesiones de datos.

ASTACKINFO( ) Function
Retorna un vector que provee información acerca del objeto en un programa, aplicación o DLL, como por ejemplo; nivel de la pila de llamadas, nombre del programa en curso, modulo, número de linea, etc.

ATAGINFO( ) Function
Crea un vector que contiene información acerca del nombre, número y tipos de índices y expresiones claves.

CursorToXML( ) Function
Convierte un cursor de Visul FoxPro a XML

EDITSOURCE( ) Function
Abre el editor visual de FoxPro y, coloca opcionalmente el cursor. Requerido por Editor de Shortcuts.

EXECSCRIPT( ) Function
Permite ejecutar líneas múltiples de código desde variables, tablas, y otro texto como runtime.

GETWORDCOUNT( ) Function
Cuenta las palabras de una cadena
cString = "AAA aaa, BBB bbb, CCC ccc."
? GetWordCount(cString) && 6 – grupos de caractéres, definidos por " "
? GetWordCount(cString, ",") && 3 - grupos de caractéres, definidos por ","
? GetWordCount(cString, ".") && 1 - grupos de caractéres, definidos por "."

GETWORDNUM( ) Function
Devuelve una palabra especificada de una cadena.
cString = "AAA aaa BBB bbb CCC ccc"
?GETWORDNUM(cString,2) && devuelve aaa
?GETWORDNUM(cString,4) && devuelve bbb

QUARTER( ) Function
Retorna el cuarto del año de una expresión fecha o datetime.

CLASES


EditorOptions Property
Esta propiedad del objeto especifica las opciones del Editor de Visual FoxPro que se habilitarán, por ejemplo.
VFP.EditorOptions = "lq" && Desabilita AUTO IntelliSense.
_VFP.EditorOptions = "LQ" && Habilita Auto IntelliSense

FoxCode Property
Especifica el nombre de la tabla FOXCODE usada por VFP7 IntelliSense, por defecto es FOXCODE y se encuentra en HOME()

FoxTask Property
Especifica el nombre de la tabla FOXTASK que soporta el administrador de tareas de VFP.

MouseEnter Event
Habilita DHTML. Ocurre cuando en cursor del mouse se mueve.

RowColChange Property
Identifica el tipo de cambio hecho en un grid.
Grid.RowColChange
0- Sin cambios.
1- Cambio de fila.
2- Cambio de columna.
3- Cambio de fila y columna.

SelectedItemBackColor, SelectedItemForeColor
Soporta colores en combobox, listbox y grid.

VisualEffect Property
Soporta SpecialEffect entre controles.

19 de septiembre de 2001

Visual Foxpro 5 , Fundamentos y Técnicas de Programación (Rubén Iglesias)

Título: Visual Foxpro 5 , Fundamentos y Técnicas de Programación
Autor: Rubén Iglesias 
ISBN : 970-15-0349-X
Editora: Ra-Ma
Nº Paginas: 491


Contenido :

  1. Bases de Datos y Tablas
  2. Instrucciones Básicas
  3. La Tecnología Rushmore
  4. Menús a la Carta
  5. Programación Orientada a Objetos
  6. Análisis y Diseño Orientado a Objetos
  7. Programación Orientada a Formularios
  8. Las clases de Base
  9. Gestion de Informes
  10. El archivo Config.fpw
  11. Aplicacion Práctica
  12. Creación de un Ajedrez
  13. Apendices

Comentario :

La explicacion que da Iglesias de el uso de cada componente es muy bien ilustrada y ejemplificada .
Las propiedades y eventos de los controles estan bien explicados . Solo faltaria hablar un poco mas de clases . Destaque capitulo 3 (Rushmore), ejemplos y explicaciones bien detalladas del uso de esta tecnologia .

Nivel : Iniciante.

18 de septiembre de 2001

Crea documentos XML anidados con VFP 7.0

LOCAL StringXML,StringXML2

***********************************************
* Aquí se crea un documento básico en XML que  contiene
* tres datos personales y un TAG vacío para las direcciones
***********************************************

StringXML=[]
StringXML = CreateDocumentXML(StringXML,"nombre","Aleix")
StringXML = CreateDocumentXML(StringXML,"apellidos","Lamela")
StringXML = CreateDocumentXML(StringXML,"dni","12345678A")
StringXML = CreateDocumentXML(StringXML,"detallesDirecciones")

***********************************************
* Ahora crearemos las direcciones de la misma manera
***********************************************

StringXML2=[]
StringXML2 = CreateDocumentXML(StringXML2,"Calle","Diagonal")
StringXML2 = CreateDocumentXML(StringXML2,"Piso","4")
StringXML2 = CreateDocumentXML(StringXML2,"Puerta","1")

***********************************************
* Aqui vamos a agregar Documento XML a otro donde nos interese.
***********************************************

LOCAL PadreXML  as msxml2.DOMDocument
LOCAL HijosXML  as msxml2.DOMDocument
LOCAL ELEMENTOS  AS MSXML2.IXMLDOMElement 
PadreXML =  CREATEOBJECT("msxml2.domdocument")
HijosXML  =  CREATEOBJECT("msxml2.domdocument")
HijosXML.async=.f.
PadreXML.async=.f.
HijosXML.loadXML(StringXML2)
PadreXML.loadXML(StringXML)
HijosXML.documentElement 
PadreXML.documentElement.selectSingleNode("detallesDirecciones").appendChild(HijosXML.documentElement)


************************************************
* Y ya esta , ahora solo tienes que mirar el contenido
***********************************************


IF MESSAGEBOX("¿Desea guardar el contenido en disco?",32+4) = 6
    PadreXML.save("c:DocumentoPersonal.xml")
ELSE
    MESSAGEBOX(PadreXML.xml)
ENDIF

RETURN

***********************************************
* Esta función Acepta Tres Parámetros, un Documento Raíz 
* , el Nuevo TAG que se le quiere agregar
* Y el Valor del Tag
***********************************************

FUNCTION CreateDocumentXML(DocumentRoot  as String,;
                                           NewElement  as String, ;
                                           NewValue  as String)
 LOCAL ElDocumento  as MSXML2.DOMDocument 
 LOCAL ELElemento  as MSXML2.IXMLDOMElement 
 LOCAL LaRaiz  as MSXML2.IXMLDOMElement 
 IF PCOUNT() >= 1  THEN 

 ***********************************************
 * Cargo el Documento nuevo
 ***********************************************

 ElDocumento =  CREATEOBJECT("MSXML2.DOMDocument")
 ElDocumento.async= .F.
 ElDocumento.loadXML(DocumentRoot)
 ENDIF
 IF PCOUNT() >= 2  THEN 

 ***********************************************
 * Extraigo los datos principales
 ***********************************************
 LaRaiz = ElDocumento.documentElement 
 ***********************************************
 * Creo el nuevo Elemento
 ***********************************************
 ElElemento = ElDocumento.createElement(NewElement)
 LaRaiz.appendChild(ElElemento)
 ENDIF
 IF PCOUNT()=3  THEN
 LaRaiz.lastChild.text = NewValue
 ENDIF

 RETURN ElDocumento.xml 
ENDFUNC

11 de septiembre de 2001

Modificar el volumen de los altavoces

Enviada al grupo de noticias por Patrick Espinosa, aqui tenemos como hacerlo ...
Declare Integer waveOutSetVolume in Winmm Integer wDeviceID, Integer dwVolume

waveOutSetVolume(0,0xFFFFFFFF)
Para poner en silencio total se debe poner 0x00000000. Los primeros 4 son para el canal (altavoz) izquierdo y los 4 de los últimos 4 para el canal derecho, por lo que por ejemplo si quieres que nada más se escuche el altavoz izquierda debes poner un 0xFFFF0000.