Page 1 of 1

Problemas al generar Indices

Posted: Thu Nov 01, 2007 1:46 am
by cuatecatl82
Saludos a todos los colegas de foro:

Haber si a alguien le ha pasado lo siguiente: :roll:

La mayoria de nosotros tenemos en nuestras aplicaciones alguna funcion que permite compactar y regenerar indices y vizualizar el progreso con un meter, antes en 16bits todo trabajaba de maravillas desde una pc en red o en una pc local, ahora con 32bits me genera el siguiente error:

Descripción del Error:
___________________________________________________

Error DBCMD/2001
Area de trabajo no usada: ORDCREATE


Llamadas al Stack:
___________________________________________________

Llamado desde ORDCREATE(0)
Llamado desde METER(1177)
Llamado desde (b)INDEXA(140)
Llamado desde (b)TDIALOG:TDIALOG(85)
Llamado desde TDIALOG:DISPLAY(0)

Estas son las funciones con que trabajo, no se si lo estoy implementando mal o si algo se me esta pasando:

(Asumo que ya estan Compactadas con ZAP las bases de Datos y eliminados los archivos indices..)

//------------------------//
FUNCTION PackBF()

LOCAL oMeter1, oPackDBase
LOCAL lSalir:= .F.

DEFINE DIALOG oPackDBase RESOURCE "OPTIMIZA" Title "Organizando Información" OF oPackDBase

oMeter1 = TProgress():Redefine( 200, oPackDBase )
oPackDBase:lHelpIcon:= .F.
bDialogTask := { || Indexa(oMeter1) }

ACTIVATE DIALOG oPackDBase CENTERED VALID (lSalir) ON PAINT EVAL(bDialogTask)


RETURN nil


//------------------------//
STATIC FUNCTION METER(oMeter)

IF !FILE(".\CLIENTES.CDX")
SET UNIQUE OFF
DBUSEAREA(.T., "DBFCDX",".\CLIENTES.DBF", "CLIENTES",.T.,.F.)
IF !NETERR()
SYSREFRESH()
PreIndex( oMeter, nRec, "CLIENTES" )
INDEX ON STRZERO( IdCliente, 10 ) TAG IdCliente FOR ! DELETED() EVAL( oMeter:SETPOS( nRec++ ), SYSREFRESH() ) <--(Aki Falla)
Postindex(nRec)
nRec := 0

SYSREFRESH()
PreIndex( oMeter, nRec, "CLIENTES" )
INDEX ON UPPER(NomClient) TAG NomClient FOR ! DELETED() EVAL( oMeter:SETPOS( nRec++ ), SYSREFRESH() ) <--(Aki Falla)
Postindex(nRec)
nRec := 0

DBSELECTAREA("CLIENTES")
DBCLOSEAREA("CLIENTES")
ENDIF
ENDIF

//------------------------//
STATIC FUNCTION PreIndex( oMeter, nRec, cAlias )

oMeter:SetRange( 0, (cAlias)->( LASTREC() ))
nRec := 0
oMeter:SETPOS(nRec)
SYSREFRESH()

RETURN nRec


//------------------------//
STATIC FUNCTION Postindex(nRec)

oMeter:SETPOS(nRec++)
SYSREFRESH()

RETURN nil

El fallo se produce en la linea donde esta el comando:

INDEX ON ..

_ de la Base de Datos CLIENTES son:

IdCliente Numerico 10
NomClient Caracter 20

Y tambien esta enlazadas las librerias para generar indices DBFCDX

Agradecería toda la ayuda que fuera posible y tambien nuevas propuestas para generar indices..

Saludos.. :lol:

Posted: Thu Nov 01, 2007 2:58 am
by joseluisysturiz
Prueba aca con
INDEX ON STRZERO( clientes->IdCliente, 10 ) TAG IdCliente FOR ! DELETED() EVAL( oMeter:SETPOS( nRec++ ), SYSREFRESH() ) <--(Aki Falla)

Si tienes varios archivos abiertos debes usar las alias para indicar cual DBF usas, espero te ayude, abajo un ejemplo que uso y nunca me ha dado error, claro no le tengo incorporado METER... pero me genera los CDX sin problemas...saludos


SET AUTOPEN OFF // IMPIDE APERTURA AUTOMATICA DE LOS BAG

IF NETERR() // CONTROL NADIE USE SISTEMA
MSGALERT("Existen Usuarios en el Sistema,"+CHR(13)+"deben Salir todos para Indexar"," ATENCIÓN")
RETURN .F.
ENDIF

* FERASE("jlinven.cdx") // PARA BORRAR TODOS LOS .CDX

USE JLBENEFI NEW // MAESTRO BENEFICIARIOS - PROVEEDORES
INDEX ON jlbenefi->BEN_CODIGO TAG CODIGO // 1 CODIGO ASCENDENTE
INDEX ON jlbenefi->BEN_NOMBRE TAG NOMBRE // 2 NOMBRE ASCENDENTE
CLOSE ALL
SET AUTOPEN ON // REACTIVAMOS APERTURA

Posted: Thu Nov 01, 2007 4:57 pm
by cuatecatl82
joseluisysturiz:


Saludos desde México :) , y agradesco por su respusta, le comento que el procedimiento lo realizo con varias bases de datos, a los cuales les asigno un alias correspondiente, de todas maneras pruebo la sugerencia que me da y comento como me fue..

Gracias.. :wink:

www.sisa.unlugar.com

I.S.C. Víctor Daniel Cuatécatl León

Posted: Wed Nov 07, 2007 6:23 pm
by cuatecatl82
Saludos de Nuevo compañeros del foro:

De nuevo molestando a toda la comunidad, he estado realizando pruebas desde hace unos días para tratar
de solucionar el problema que tengo al reindexar las 25 bases de datos de mi sistema, estuve buscando y
probando varias opciones y nada funciona ya que ahora me genera el siguiente error:

hb_cdxIndexFree: index file still locked.

He buscado en la red pero no encuentro respuesta a como solucionar este error, solo si borro manualmente
los indices puedo trabajar y al volver a reindexar aparece otro error:

Error DBCMD/2001
Area de trabajo no usada: ORDCREATE

Para evitar éste último error me sugirieron que realizara _:

SET AUTOPEN OFF
DBUSEAREA(.T., "DBFCDX",".\PROVEDOR", "PROVEDOR",.F.,.F.)
IF !NETERR()
FERASE(".\PROVEDOR.CDX")

PreIndex( oMeter, nRec, "PROVEDOR")
INDEX ON STRZERO(PROVEDOR->NumId,5) TAG NumId FOR ! DELETED() EVAL( oMeter:SETPOS( nRec++ ), SYSREFRESH() )
Postindex(nRec)
nRec:= 0
ENDIF
DBSELECTAREA("PROVEDOR")
PROVEDOR->(DBCLOSEAREA())
SET AUTOPEN ON

ya que antes estaba así (sin Autopen xxx):

DBUSEAREA(.T., "DBFCDX",".\PROVEDOR", "PROVEDOR",.F.,.F.)
IF !NETERR()
FERASE(".\PROVEDOR.CDX")

PreIndex( oMeter, nRec, "PROVEDOR")
INDEX ON STRZERO(NumId,5) TAG NumId FOR ! DELETED() EVAL( oMeter:SETPOS( nRec++ ), SYSREFRESH() )
Postindex(nRec)
nRec:= 0
ENDIF
DBSELECTAREA("PROVEDOR")
DBCLOSEAREA("PROVEDOR")

Y es que creo que a casi nadie le ha ocurido esto porque solo encontre un enlace con el mismo problema
pero no comentan como lo soluciono.

http://fivetechsoft.com/forums/viewtopi ... 1b4fcaf8b6

Así que de nuevo recurro a la comunidad para que me orienten y me ayuden a solucionar este problema
ya que como muchos sabemos la reindexacion es solo una utilidad que casi no tiene importancia, pero que
garantizan que nuestras aplicaciones trabajen de forma optimizada...

Ojala y el maestro Antonio Linares tenga un tiempesito y le de una revisada para que me de mi respectivo
jalón de orejas... :oops:

Saludos...

ASI ME FUNCIONA

Posted: Wed Nov 07, 2007 7:30 pm
by Ramon Paredes
Estimado cuatecatl82 :

Yo no he tenido problemas con la generacion de los indices, lo hago de la siguiente manera :

- tengo una tabla llamada LISTADBF con los siguientes campos:

NOMDBF Caracter 12 ( Nombre de la Tabla en mi Programa)
MARCA Numerico 1 ( Marca para generar o no el indice )
CONCEPTO Caracter 40 (Breve descricion de la tabla )

- Tengo otra tabla llamada INDICES con los siguientes campos :

NOMDBF Caracter 12 ( Nombre de cada tabla de mi programa)
Nomcam Caracter 50 (Campos por los que creo cada indice)
NOMNTX Caracter 12 ( Nombre del indice)

Para generar los indices uso la siguiente funcion :

//==================
FUNCTION INDICES()
//==================
LOCAL oDlg, oLbx, oFont1

LOCAL aHBitMaps:= { ReadBitmap( 0, "Check1.bmp" ), ;
ReadBitmap( 0, "Check2.bmp" ) }

LOCAL n

** Genera el Archivo Tag

// BORRO LOS INDICES DE LAS TABLAS

FERASE("LISTADBF.CDX")
FERASE("INDICES.CDX")


SELECT A
IF ABRE_BD("LISTADBF",.T.) = .F.
CLOSE DATA
RETURN NIL
ENDIF
INDEX ON LISTADBF->Nomdbf TAG Listad1
CLOSE DATA

SELECT A
IF ABRE_BD("INDICES",.T.) = .F.
CLOSE DATA
RETURN NIL
ENDIF
INDEX On INDICES->nomdbf TAG Iindex1
CLOSE DATA

SELECT C
IF ABRE_BD("LISTADBF",.T.) = .F.
CLOSE DATA
RETURN NIL
ENDIF
SET INDEX TO listadbf
GO TOP

SELECT A
IF ABRE_BD("INDICES",.T.) = .F.
CLOSE DATA
RETURN NIL
Endif
SET INDEX TO INDICES

DEFINE FONT oFont1 NAME "Tahoma" size 0,14 BOLD
ACTIVATE FONT oFont1

DEFINE DIALOG oDlg FROM 3, 3 TO 26, 79 TITLE "Mantenimiento a Indices del Sistema"

@ 0, 1 SAY " &Indices del Sistema" OF oDlg

SELECT C

@ 1, 1 LISTBOX oLbx FIELDS aHBitmaps[ Max( 1, C->Marca ) ],;
C->nomdbf, C->Concepto ;
HEADERS "S", "Tabla", "Descripcion de la Tabla" ;
FIELDSIZES 20, 64, 400 ;
SIZE 284, 137 OF oDlg ;
FONT oFont1

oLbx:bLClicked = { || MarcaReg(oLbx) }
oLbx:nLineStyle = 1
oLbx:aJustify = { .T., .f., .f.}
oLbx:bRClicked = { || oLbx:ShowSizes() }


@ 8.7, 1.4 BUTTON "&Todos" OF oDlg ACTION SelTodo( oLbx, 2 ) SIZE 40, 12
@ 8.7, 9.4 BUTTON "&Ninguno" OF oDlg ACTION SelTodo( oLbx, 1 ) SIZE 40, 12
@ 8.7, 17.4 BUTTON "&Generar" OF oDlg ACTION GeneraI( oLbx, oDlg ) SIZE 40, 12
@ 8.7, 25.4 BUTTON "&Salir" OF oDlg ACTION oDlg:End() SIZE 40, 12

ACTIVATE DIALOG oDlg CENTERED

AEval( aHBitmaps, { | hBmp | DeleteObject( hBmp ) } )
RELEASE FONT oFont1

RETURN NIL


// Funcion para Marcar Registro
//============================
STATIC FUNCTION MarcaReg(oLbx)
//============================

IF C->marca = 1
C->Marca := 2
ELSE
C->Marca := 1
ENDIF

oLbx:Refresh() // Refresca el Listbox (Los datos de la tabla)

RETURN .T.

// Funcion para Marcar/Desmarcar todos
//==================================
STATIC FUNCTION SelTodo(oLbx,fMarca)
//==================================

SELECT C
GO TOP
DO WHILE .NOT. EOF()
C->Marca := fMarca
SKIP
ENDDO
GO TOP

oLbx:Refresh() // Refresca el Listbox (Los datos de la tabla)

RETURN .T.

// Funcion para Generar Archivos Indices
//================================
STATIC FUNCTION GeneraI(oLbx,oDlg)
//================================

LOCAL wnomdbf,mfil_dbf,mfil_cdx

SELECT C
GO TOP

DO WHILE ! EOF()

IF C->Marca = 2
wnomdbf = C->nomdbf
mFil_dbf := ALLTRIM(C->nomdbf)+".DBF"
mFil_cdx := ALLTRIM(C->nomdbf)+".CDX"

IF !FILE(mFil_dbf)
MSGALERT("No Existe La Base De Datos "+MFIL_DBF,"Error Indices")
RETURN .F.
ENDIF

FERASE(mfil_cdx)

SELECT B

IF ABRE_BD(mFil_Dbf,.T.) = .f.
CLOSE DATA
RETURN .F.
ENDIF
PACK

SELECT A
SEEK wnomdbf
IF FOUND()
IF !GEN_IND(oLbx,oDlg,mfil_dbf,mfil_cdx)
RETURN .F.
ENDIF
ENDIF
ENDIF

SELECT C
SKIP
ENDDO

SELECT C
GO TOP

oLbx:Refresh() // Refresca el Listbox (Los datos de la tabla)

RETURN .T.

//===========================================
FUNCTION GEN_IND(oLbx,oDlg,ffil_dbf,ffil_cdx)
//===========================================
LOCAL mConcep, mempaque, l1_file,mfil_ntx

l1_file := A->nomdbf

DO WHILE l1_file == A->nomdbf

mcampo := ALLTRIM(A->nomcam)
mFil_ntx := ALLTRIM(A->nomntx)
mConcep := ALLTRIM(A->concep)

// mEmpaque := A->empaque

SELECT B

MSGMETER( { | oMeter, oText, oDlg, lEnd | ;
CreaIndex( oMeter, oText, oDlg, @lEnd,mfil_ntx ) },;
"Tabla : " + ffil_dbf+" Tag : "+mfil_ntx,"Generando Indices")

SELECT A
SKIP
ENDDO

RETURN .T.

//======================================================
FUNCTION CREAINDEX( oMeter, oText, oDlg, lEnd,mfil_ntx )
//======================================================
oMeter:nTotal = RECCOUNT()

INDEX ON &MCAMPO TAG (mFil_Ntx) TO (mfil_cdx) ;
EVAL ( oMeter:SET( RECNO() ), SysRefresh(), ! lEnd )

RETURN NIL

//================================
Function ABRE_BD(FBase,fTipo)
//================================

LOCAL mSioNo, Regre

Do While .T.

If ftipo = .t.
Use (fBase) Exclusive
Else
Use (fbase) Shared
Endif

If !NetErr()
Regre = .T.
Exit
Else
mSioNo = MsgNoYes("La base de datos " + fbase +" esta siendo utilizada por otro usuario, Desea Volver a Intentar? " , "Error al abrir")
If mSioNo
loop
Else
Regre = .F.
Exit
Endif

Endif

EndDo

Return Regre

Espero te sea de alguna utilidad,

Ramon Antonio Paredes
Managua, Nicaragua