diff --git a/Convert_VFP9_BIN_2_PRG.vbs b/Convert_VFP9_BIN_2_PRG.vbs index eae6e93..291d181 100644 --- a/Convert_VFP9_BIN_2_PRG.vbs +++ b/Convert_VFP9_BIN_2_PRG.vbs @@ -16,6 +16,8 @@ Const ForReading = 1 Dim WSHShell, FileSystemObject, cEndOfProcessMsg, cWithErrorsMsg, cConvCancelByUserMsg, nProcessedFilesCount Dim oVFP9, nExitCode, cEXETool, cCMD, nDebug, lcExt, foxbin2prg_cfg, aFiles(), nFile_Count Dim i, x, str_cfg, aConf, cErrMsg, cFlagGenerateLog, cFlagDontShowErrMsg, cFlagJustShowCall, cFlagRecompile, cFlagNoTimestamps, cErrFile +'' 2016.04.05 DH: added next line +dim fileToProcess Set WSHShell = WScript.CreateObject("WScript.Shell") Set FileSystemObject = WScript.CreateObject("Scripting.FileSystemObject") Set oVFP9 = CreateObject("VisualFoxPro.Application.9") @@ -29,7 +31,7 @@ nExitCode = 0 ' 4=Don't show FoxBin2prg error modal messages ' 8=Show end of process message ' 16=Empty timestamps -nDebug = 1+0+4+8 +nDebug = 1+0+4+8+16 '--------------------------------------------------------------------------------------------------- If WScript.Arguments.Count = 0 Then @@ -68,8 +70,11 @@ Else cFlagGenerateLog = "'0'" cFlagDontShowErrMsg = "'0'" - cFlagShowCall = "'0'" + '' 2016.04.05 DH: fixed incorrectly named variable + cFlagJustShowCall = "'0'" cFlagRecompile = "'1'" + '' 2016.04.05 DH: added missing assignment + cFlagNoTimestamps = "'0'" If GetBit(nDebug, 1) Then cFlagGenerateLog = "'1'" @@ -87,13 +92,17 @@ Else oVFP9.DoCmd( "oFoxBin2prg.o_frm_avance.Caption = '" & FileSystemObject.GetBaseName( WScript.ScriptName ) & " - ' + oFoxBin2Prg.c_loc_process_progress + ' (Press Esc to Cancel)'" ) For i = 1 To nFile_Count - oVFP9.DoCmd( "oFoxBin2Prg.updateProgressbar(oFoxBin2Prg.c_loc_processing_file + ' " & aFiles(i) & "...', " & i & ", " & nFile_Count & ", 0)" ) - cFlagRecompile = "'" & FileSystemObject.GetParentFolderName( aFiles(i) ) & "'" - + '' 2016.04.05 DH: put double quotes around path in case in contains single quote + fileToProcess = Chr(34) + aFiles(i) + Chr(34) + oVFP9.DoCmd( "oFoxBin2Prg.updateProgressbar(oFoxBin2Prg.c_loc_processing_file + " & fileToProcess & ", " & i & ", " & nFile_Count & ", 0)" ) + cFlagRecompile = Chr(34) + FileSystemObject.GetParentFolderName( aFiles(i) ) + Chr(34) + '' 2016.04.05 DH: end of change If nDebug = 0 Or nDebug = 2 Then - cCMD = "oFoxBin2prg.execute( '" & aFiles(i) & "' )" + '' 2016.04.05 DH: use new variable + cCMD = "oFoxBin2prg.execute(" & fileToProcess & ")" Else - cCMD = "oFoxBin2prg.execute( '" & aFiles(i) & "','BIN2PRG','0','0'," _ + '' 2016.04.05 DH: use new variable + cCMD = "oFoxBin2prg.execute(" & fileToProcess & ",'BIN2PRG','0','0'," _ & cFlagDontShowErrMsg & "," & cFlagGenerateLog & ",'1','','',.F.,''," _ & cFlagRecompile & "," & cFlagNoTimestamps & " )" End If diff --git a/Convert_VFP9_PRG_2_BIN.vbs b/Convert_VFP9_PRG_2_BIN.vbs index d6c1587..ae90f6c 100644 --- a/Convert_VFP9_PRG_2_BIN.vbs +++ b/Convert_VFP9_PRG_2_BIN.vbs @@ -16,6 +16,8 @@ Const ForReading = 1 Dim WSHShell, FileSystemObject, cEndOfProcessMsg, cWithErrorsMsg, cConvCancelByUserMsg, nProcessedFilesCount Dim oVFP9, nExitCode, cEXETool, cCMD, nDebug, lcExt, foxbin2prg_cfg, aFiles(), nFile_Count Dim i, x, str_cfg, aConf, cErrMsg, cFlagGenerateLog, cFlagDontShowErrMsg, cFlagJustShowCall, cFlagRecompile, cFlagNoTimestamps, cErrFile +'' 2016.04.05 DH: added next line +dim fileToProcess Set WSHShell = WScript.CreateObject("WScript.Shell") Set FileSystemObject = WScript.CreateObject("Scripting.FileSystemObject") Set oVFP9 = CreateObject("VisualFoxPro.Application.9") @@ -29,7 +31,7 @@ nExitCode = 0 ' 4=Don't show FoxBin2prg error modal messages ' 8=Show end of process message ' 16=Empty timestamps -nDebug = 1+0+4+8 +nDebug = 1+0+4+8+16 '--------------------------------------------------------------------------------------------------- If WScript.Arguments.Count = 0 Then @@ -75,7 +77,10 @@ Else cFlagGenerateLog = "'0'" cFlagDontShowErrMsg = "'0'" - cFlagShowCall = "'0'" + '' 2016.04.05 DH: fixed incorrectly named variable + cFlagJustShowCall = "'0'" + '' 2016.04.05 DH: added missing assignment + cFlagNoTimestamps = "'0'" If GetBit(nDebug, 1) Then cFlagGenerateLog = "'1'" @@ -93,13 +98,18 @@ Else oVFP9.DoCmd( "oFoxBin2prg.o_frm_avance.Caption = '" & FileSystemObject.GetBaseName( WScript.ScriptName ) & " - ' + oFoxBin2Prg.c_loc_process_progress + ' (Press Esc to Cancel)'" ) For i = 1 To nFile_Count - oVFP9.DoCmd( "oFoxBin2Prg.updateProgressbar(oFoxBin2Prg.c_loc_processing_file + ' " & aFiles(i) & "...', " & i & ", " & nFile_Count & ", 0)" ) - cFlagRecompile = "'" & FileSystemObject.GetParentFolderName( aFiles(i) ) & "'" + '' 2016.04.05 DH: put double quotes around path in case in contains single quote + fileToProcess = Chr(34) + aFiles(i) + Chr(34) + oVFP9.DoCmd( "oFoxBin2Prg.updateProgressbar(oFoxBin2Prg.c_loc_processing_file + " & fileToProcess & ", " & i & ", " & nFile_Count & ", 0)" ) + cFlagRecompile = Chr(34) + FileSystemObject.GetParentFolderName( aFiles(i) ) + Chr(34) + '' 2016.04.05 DH: end of change If nDebug = 0 Or nDebug = 2 Then - cCMD = "oFoxBin2prg.execute( '" & aFiles(i) & "' )" + '' 2016.04.05 DH: use new variable + cCMD = "oFoxBin2prg.execute(" & fileToProcess & ")" Else - cCMD = "oFoxBin2prg.execute( '" & aFiles(i) & "','PRG2BIN','0','0'," _ + '' 2016.04.05 DH: use new variable + cCMD = "oFoxBin2prg.execute(" & fileToProcess & ",'PRG2BIN','0','0'," _ & cFlagDontShowErrMsg & "," & cFlagGenerateLog & ",'1','','',.F.,''," _ & cFlagRecompile & "," & cFlagNoTimestamps & " )" End If diff --git a/FileName_Caps/CONFIG/config.fpw b/FileName_Caps/CONFIG/config.fpw new file mode 100644 index 0000000..ef3f93b --- /dev/null +++ b/FileName_Caps/CONFIG/config.fpw @@ -0,0 +1,2 @@ +SCREEN=OFF +RESOURCE=OFF \ No newline at end of file diff --git a/FileName_Caps/Filename_caps.pj2 b/FileName_Caps/Filename_caps.pj2 new file mode 100644 index 0000000..24e849d --- /dev/null +++ b/FileName_Caps/Filename_caps.pj2 @@ -0,0 +1,87 @@ +*-------------------------------------------------------------------------------------------------------------------------------------------------------- +* (ES) AUTOGENERADO - ¡¡ATENCIÓN!! - ¡¡NO PENSADO PARA EJECUTAR!! USAR SOLAMENTE PARA INTEGRAR CAMBIOS Y ALMACENAR CON HERRAMIENTAS SCM!! +* (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!! +*-------------------------------------------------------------------------------------------------------------------------------------------------------- +*< FOXBIN2PRG: Version="1.19" SourceFile="filename_caps.pjx" /> (Solo para binarios VFP 9 / Only for VFP 9 binaries) +* +LPARAMETERS tcDir + +lcCurdir = SYS(5)+CURDIR() +CD ( EVL( tcDir, JUSTPATH( SYS(16) ) ) ) + +* +_Author = "" +_Company = "" +_Address = "" +_City = "" +_State = "" +_PostalCode = "" +_Country = "" +*-- +_Comments = "Capitalization for files" +_CompanyName = "Fernando D. Bozzo" +_FileDescription = "Capitalization for files" +_LegalCopyright = "Creative Commons 4: Reconocimiento - CompartirIgual (by-sa): http://creativecommons.org/licenses/by/4.0/" +_LegalTrademark = "Creative Commons 4: Reconocimiento - CompartirIgual (by-sa): http://creativecommons.org/licenses/by/4.0/" +_ProductName = "FILENAME_CAPS" +_MajorVer = "2" +_MinorVer = "3" +_Revision = "0" +_LanguageID = "" +_AutoIncrement = "0" +* + + +* +*<.HomeDir = 'c:\desa\filename_caps' /> + +FOR EACH loProject IN _VFP.Projects FOXOBJECT + loProject.Close() +ENDFOR + +STRTOFILE( '', '__newproject.f2b' ) +BUILD PROJECT Filename_caps.pjx FROM '__newproject.f2b' +FOR EACH loProject IN _VFP.Projects FOXOBJECT + loProject.Close() +ENDFOR + +MODIFY PROJECT 'Filename_caps.pjx' NOWAIT NOSHOW NOPROJECTHOOK + +loProject = _VFP.Projects('Filename_caps.pjx') + +WITH loProject.FILES + .ADD('config\config.fpw') && *< FileMetadata: Type="T" Cpid="1252" Timestamp="0" ID="0" ObjRev="0" /> + .ADD('filename_caps.prg') && *< FileMetadata: Type="P" Cpid="1252" Timestamp="0" ID="0" ObjRev="544" /> + * + + .ITEM('__newproject.f2b').Remove() + + * + * + + * + * + + * + .ITEM(lcCurdir + 'config\config.fpw').Type = 'T' + * +ENDWITH + +WITH loProject + * + .SetMain(lcCurdir + 'filename_caps.prg') + .Debug = .T. + .Encrypted = .F. + *<.CmntStyle = 1 /> + *<.NoLogo = .F. /> + *<.SaveCode = .T. /> + .ProjectHookLibrary = '' + .ProjectHookClass = '' + * +ENDWITH + + +_VFP.Projects('Filename_caps.pjx').Close() +*ERASE '__newproject.f2b' +CD (lcCurdir) +RETURN \ No newline at end of file diff --git a/FileName_Caps/Filename_caps.pjt b/FileName_Caps/Filename_caps.pjt new file mode 100644 index 0000000..7061166 Binary files /dev/null and b/FileName_Caps/Filename_caps.pjt differ diff --git a/FileName_Caps/Filename_caps.pjx b/FileName_Caps/Filename_caps.pjx new file mode 100644 index 0000000..96f0b1a Binary files /dev/null and b/FileName_Caps/Filename_caps.pjx differ diff --git a/FileName_Caps/Normalize_FileNames.vbs b/FileName_Caps/Normalize_FileNames.vbs new file mode 100644 index 0000000..e06849f --- /dev/null +++ b/FileName_Caps/Normalize_FileNames.vbs @@ -0,0 +1,96 @@ +'--------------------------------------------------------------------------------------------------- +' Normalize_FileNames.vbs - 06/01/2014 - Fernando D. Bozzo (fdbozzo@gmail.com) +'--------------------------------------------------------------------------------------------------- +' ENGLISH: +' Create a shortcut on user's "SendTo" folder and configure CAPS on filename_caps.cfg +' +' ESPAÑOL: +' Cree un acceso directo en la carpeta "SendTo" del usuario y configure las Capitalizaciones en filename_caps.cfg +'--------------------------------------------------------------------------------------------------- +Const ForReading = 1 +Dim WSHShell, FileSystemObject +Dim oVFP9, nExitCode, cEXETool, cCMD, nDebug, cConvertType, aExtensions(8), filename_caps_log +Dim i, x, str_cfg, aConf +Set WSHShell = WScript.CreateObject("WScript.Shell") +Set FileSystemObject = WScript.CreateObject("Scripting.FileSystemObject") +Set oVFP9 = CreateObject("VisualFoxPro.Application.9") +filename_caps_log = Replace(WScript.ScriptFullName, WScript.ScriptName, "filename_caps.log") +nExitCode = 0 +'--------------------------------------------------------------------------------------------------- +nDebug = 5 'Cumulative Flags: 0=OFF, 1=Create filename_caps LOG, 2=Only show script calls, 4=Don't show filename_caps error modal messages +'--------------------------------------------------------------------------------------------------- + +If WScript.Arguments.Count = 0 Then + nExitCode = 1 + cErrMsg = "nDebug = " & nDebug + If GetBit(nDebug, 1) Then + cErrMsg = cErrMsg & Chr(13) & "Bit 0 ON: (1) Create filename_caps LOG" + End If + If GetBit(nDebug, 2) Then + cErrMsg = cErrMsg & Chr(13) & "Bit 1 ON: (2) Only show script calls" + End If + If GetBit(nDebug, 3) Then + cErrMsg = cErrMsg & Chr(13) & "Bit 2 ON: (4) Don't show filename_caps error modal messages" + End If + MsgBox cErrMsg, 64, "No parameters - Debug Status" +Else + cEXETool = Replace(WScript.ScriptFullName, WScript.ScriptName, "filename_caps.exe") + If GetBit(nDebug, 1) And Not GetBit(nDebug, 2) And Not FileSystemObject.FileExists( filename_caps_log ) Then + FileSystemObject.CreateTextFile( filename_caps_log ) + End If + + For i = 0 To WScript.Arguments.Count-1 + scanDirs( WScript.Arguments(i) ) + Next +End If + +WScript.Quit(nExitCode) + + +Private Sub scanDirs( tcArgument ) + Dim omFolder, oFolder + If FileSystemObject.FolderExists( tcArgument ) Then + '-- Es un directorio + Set omFolder = FileSystemObject.GetFolder( tcArgument ) + For Each oFile IN omFolder.Files + evaluateFile( oFile.Path ) + Next + For Each oFolder IN omFolder.SubFolders + scanDirs( oFolder.Path ) + Next + Else + '-- Es un archivo + evaluateFile( tcArgument ) + End If +End Sub + + +Private Sub evaluateFile( tcFile ) + cFlagGenerateLog = "'0'" + cFlagDontShowErrMsg = "'0'" + cFlagShowCall = "'0'" + If GetBit(nDebug,1) Then + cFlagGenerateLog = "'1'" + End If + If GetBit(nDebug,2) Then + cFlagJustShowCall = "1" + End If + If GetBit(nDebug,3) Then + cFlagDontShowErrMsg = "'1'" + End If + + cCMD = "DO '" & cEXETool & "' WITH '" & tcFile & "','','F','',.F.," & cFlagDontShowErrMsg + If cFlagJustShowCall = "1" Then + MsgBox cCMD, 0, "PARAMETROS ENVIADOS" + Else + oVFP9.DoCmd( cCMD ) + 'nExitCode = oVFP9.Eval("_SCREEN.ExitCode") + End If +End Sub + + +Function GetBit(lngValue, BitNum) + Dim BitMask + If BitNum < 32 Then BitMask = 2 ^ (BitNum - 1) Else BitMask = "&H80000000" + GetBit = CBool(lngValue AND BitMask) +End Function diff --git a/FileName_Caps/filename_caps.cfg b/FileName_Caps/filename_caps.cfg new file mode 100644 index 0000000..40a8b55 --- /dev/null +++ b/FileName_Caps/filename_caps.cfg @@ -0,0 +1,25 @@ +*-------------------------------------------------------------------------------------- +* FILENAME_CAPS.CFG +* +* FORMATO DE MÁSCARAS: +* -------------------- +* filemask=FileName.Ext:FileNameCAPS.ExtCAPS +* Donde: FileName ==> Es el nombre del archivo +* Ext ==> Es la extensión +* FileNameCAPS ==> (U)ppercase, (L)owercase, (P)roper, (M)atch, (N)o change +* ExtCAPS ==> (U)ppercase, (L)owercase, (P)roper, (M)atch, (N)o change +* +* EJEMPLOS DE MÁSCARAS: +* --------------------- +* filemask=*.PDF:U.L ==> Convierte los archivos PDF a +* filemask=*.DOT:L.U ==> Convierte los archivos DOT a +* filemask=*.PRG:C.L ==> Convierte un archivo específico a +* filemask=EJeMPLo.ini:M.U ==> Convierte un archivo específico a +* filemask=EjEmPlO.ini:P.U ==> Convierte un archivo específico a +* +* IMPORTANTE: +* ----------- +* LAS CONVERSIONES SE REALIZAN EN EL ORDEN QUE SE PONGAN, COMENZANDO POR ARRIBA. +*-------------------------------------------------------------------------------------- +filemask=README.ini:M.M +filemask=*.*:N.L diff --git a/FileName_Caps/filename_caps.prg b/FileName_Caps/filename_caps.prg new file mode 100644 index 0000000..7c07146 --- /dev/null +++ b/FileName_Caps/filename_caps.prg @@ -0,0 +1,210 @@ +*-------------------------------------------------------------------------------------------------------------- +*-- FileName_Caps.PRG +*-- CAPITALIZA EL NOMBRE Y EXTENSIÓN DEL ARCHIVO INDICADO SEGÚN LA CONFIGURACIÓN INDICADA +*-- Fernando D. Bozzo - 24/12/2013 +*-------------------------------------------------------------------------------------------------------------- +* EJEMPLOS CON MÁSCARAS IN-LINE (SIN ARCHIVO CONFIG): +* filename_caps( 'un_EjeMplo.PrG', '*.pRg:M.M' ) ==> 'un_EjeMplo.PrG' +* filename_caps( 'un_EjeMplo.PrG', '*.pRg:U.L' ) ==> 'UN_EJEMPLO.prg' +* filename_caps( 'un_EjeMplo.PrG', '*.pRg:P.U' ) ==> 'Un_ejemplo.PRG' +* filename_caps( 'UN_EJEMPLO.PRG', 'un_EjeMplo.pRg:M.M' ) ==> 'un_EjeMplo.pRg' +* +* EJEMPLO CON MÁSCARAS EN ARCHIVO CONFIG 'filename_caps.cfg': +* filemask=*.TXT:P.L +* filemask=*.PDF:U.L +* filemask=*.APP:P.U +* filemask=un_EjeMplo.pRg:M.M +* +* filename_caps( 'UN_EJEMPLO.TXT', 'filename_caps.cfg', 'F' ) ==> 'Un_ejemplo.prg' +* filename_caps( 'un_ejemplo.PDF', 'filename_caps.cfg', 'F' ) ==> 'UN_EJEMPLO.prg' +* filename_caps( 'un_ejemplo.prg', 'filename_caps.cfg', 'F' ) ==> 'Un_ejemplo.PRG' +* filename_caps( 'UN_EJEMPLO.PRG', 'filename_caps.cfg', 'F' ) ==> 'un_EjeMplo.PrG' +*-------------------------------------------------------------------------------------------------------------- +* PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT) +* tcFileName (!v IN ) Archivo a capitalizar +* tcFileMask (?v IN ) Mascara de archivo o archivo de configuración de máscaras (U,L,P,N,M) +* => Significado: (U)pper,(L)ower,(P)roper,(M)atch,(N)one +* tcFileMaskType (?v IN ) 'M' o nada=FileMask es una máscara, 'F'=FileMask es un archivo config. +* tcLog (?@ OUT) Log generado por este programa +* tlRelanzarError (?v IN ) Indica si el error se debe relanzar (THROW) o no +* tcDontShowErrors (?v IN ) '1'=Don't show errors, Otherwise=Show errors +*-------------------------------------------------------------------------------------------------------------- +LPARAMETERS tcFileName, tcFileMask, tcFileMaskType, tcLog, tlRelanzarError, tcDontShowErrors + +#DEFINE CR_LF CHR(13)+CHR(10) + +LOCAL lcFileName ; + , loFNC AS cl_FileName_Caps OF FileName_Caps.prg ; + , loEx AS EXCEPTION + +loFNC = CREATEOBJECT("cl_FileName_Caps") +lcFileName = loFNC.Capitalize( tcFileName, tcFileMask, tcFileMaskType, tcLog, tlRelanzarError, tcDontShowErrors ) + +RETURN lcFileName + + +DEFINE CLASS cl_FileName_Caps AS Custom + + PROCEDURE Capitalize + LPARAMETERS tcFileName, tcFileMask, tcFileMaskType, tcLog, tlRelanzarError, tcDontShowErrors + + TRY + LOCAL loEx AS EXCEPTION, laMasks(1,4), lcDefinition, lcFileDef, lcMaskDef, laLines(1), lcMenErr ; + , I, X, lcName, lcExt, lcPath, lcFileName, laFile(1,5), lcLogFile, lcSys16, lnPosProg ; + , loFSO AS Scripting.FileSystemObject + + loEx = NULL + loFSO = CREATEOBJECT('Scripting.FileSystemObject') + tcFileMaskType = EVL(tcFileMaskType,'M') + lcFileName = tcFileName + lcLogFile = FORCEEXT(SYS(16),'LOG') + tcLog = '' + tcDontShowErrors = EVL( tcDontShowErrors, '0' ) + + IF EMPTY(tcFileMask) + IF tcFileMaskType <> 'F' + tcLog = tcLog + CR_LF + '- No hay máscara definida ni archivo de configuración' + EXIT && No se indicó nada que hacer + ELSE + lcSys16 = SYS(16) + IF LEFT(lcSys16,10) == 'PROCEDURE ' + lnPosProg = AT(" ", lcSys16, 2) + 1 + ELSE + lnPosProg = 1 + ENDIF + + tcFileMask = FORCEEXT( SUBSTR( lcSys16, lnPosProg ), 'CFG' ) + tcLog = tcLog + CR_LF + '- Se usará el archivo de configuración [' + tcFileMask + ']' + IF NOT FILE(tcFileMask) + ERROR 'El archivo de configuración de FileName_CAPS [' + tcFileMask + '] no existe!' + ENDIF + ENDIF + ENDIF + + IF tcFileMaskType == 'M' && Máscara in-line + *-- Estructura: Filename.Ext:FNameMask.ExtMask;... + tcLog = tcLog + CR_LF + '- Máscaras definidas: [' + tcFileMask + ']' + FOR I = 1 TO OCCURS( ';', tcFileMask + ';' ) + lcDefinition = GETWORDNUM( tcFileMask + ';', I, ';' ) + lcFileDef = GETWORDNUM( lcDefinition, 1, ':' ) + lcMaskDef = GETWORDNUM( lcDefinition, 2, ':' ) + laMasks(I,1) = JUSTSTEM( lcFileDef ) + laMasks(I,2) = JUSTEXT( lcFileDef ) + laMasks(I,3) = JUSTSTEM( lcMaskDef ) + laMasks(I,4) = JUSTEXT( lcMaskDef ) + ENDFOR + ELSE && Archivo de configuración + *-- Estructura: + * filemask=Filename.Ext:FilenameCap.ExtCap => Cap: (U)pper,(L)ower,(P)roper,(M)atch,(N)one + * filemask=*.PDF:U.L ==> + * filemask=*.DOT:L.U ==> + * filemask=*.PRG:C.N ==> + * filemask=EjEmPlO.iNi:C.N ==> + X = 0 + FOR I = 1 TO ALINES( laLines, FILETOSTR( tcFileMask ), 1+4 ) + IF LOWER( LEFT( laLines(I), 8 ) ) == 'filemask' + tcLog = tcLog + CR_LF + '- Se encontró la máscara: [' + laLines(I) + ']' + X = X + 1 + lcDefinition = GETWORDNUM( laLines(I), 2, '=' ) + lcFileDef = GETWORDNUM( lcDefinition, 1, ':' ) + lcMaskDef = GETWORDNUM( lcDefinition, 2, ':' ) + DIMENSION laMasks(X,4) + laMasks(X,1) = JUSTSTEM( lcFileDef ) && Name + laMasks(X,2) = JUSTEXT( lcFileDef ) && Ext + laMasks(X,3) = JUSTSTEM( lcMaskDef ) && Name Mask + laMasks(X,4) = JUSTEXT( lcMaskDef ) && Ext Mask + ENDIF + ENDFOR + ENDIF + + *-- FileName: "c:\desa\sourcesafe\myfile.ext" + lcPath = JUSTPATH( lcFileName ) + lcName = JUSTSTEM( lcFileName ) + lcExt = JUSTEXT( lcFileName ) + + FOR I = 1 TO ALEN( laMasks, 1 ) + IF LIKE( UPPER( FORCEEXT( laMasks(I,1), laMasks(I,2) ) ), UPPER( FORCEEXT( lcName, lcExt ) ) ) + *-- EVALUACIÓN DEL NOMBRE + DO CASE + CASE UPPER(laMasks(I,3)) == 'U' + lcFileName = UPPER(lcName) + CASE UPPER(laMasks(I,3)) == 'L' + lcFileName = LOWER(lcName) + CASE UPPER(laMasks(I,3)) == 'P' + lcFileName = PROPER(lcName) + CASE UPPER(laMasks(I,3)) == 'N' + lcFileName = lcName + OTHERWISE && (M)atch: Tal cual aparece definido + IF '?' $ laMasks(I,1) OR '*' $ laMasks(I,1) + ERROR 'Para (M)atch no puede usar máscara "' + laMasks(I,1) + '"' + ENDIF + lcFileName = laMasks(I,1) + ENDCASE + + *-- EVALUACIÓN DE LA EXTENSIÓN + DO CASE + CASE UPPER(laMasks(I,4)) == 'U' + lcFileName = FORCEEXT( lcFileName + '.' + lcExt, UPPER(lcExt) ) + CASE UPPER(laMasks(I,4)) == 'L' + lcFileName = FORCEEXT( lcFileName + '.' + lcExt, LOWER(lcExt) ) + CASE UPPER(laMasks(I,4)) == 'P' + lcFileName = FORCEEXT( lcFileName + '.' + lcExt, PROPER(lcExt) ) + CASE UPPER(laMasks(I,4)) == 'N' + lcFileName = FORCEEXT( lcFileName + '.' + lcExt, lcExt ) + OTHERWISE && (M)atch: Tal cual aparece definido + IF '?' $ laMasks(I,1) OR '*' $ laMasks(I,1) + ERROR 'Para (M)atch no puede usar máscara "' + laMasks(I,1) + '"' + ENDIF + lcFileName = FORCEEXT( lcFileName + '.' + lcExt, laMasks(I,2) ) + ENDCASE + + lcFileName = FORCEPATH( lcFileName, lcPath ) + tcLog = tcLog + CR_LF + '- El archivo se debe renombrar a [' + lcFileName + ']' + EXIT + ENDIF + ENDFOR + + IF ADIR( laFile, lcFileName, '', 1 ) > 0 AND laFile(1,1) <> JUSTFNAME(lcFileName) + loFSO.MoveFile( FORCEPATH( laFile(1,1), JUSTPATH(lcFileName) ), lcFileName ) + tcLog = tcLog + CR_LF + ' => Se renombrará a [' + lcFileName + ']' + ELSE + tcLog = tcLog + CR_LF + ' => No se renombrará a [' + lcFileName + '] porque ya estaba correcto.' + ENDIF + + + CATCH TO loEx + IF tlRelanzarError THEN + THROW + ELSE + IF '800a0046:' $ loEx.Details + tcLog = tcLog + CR_LF + ' => No se renombrará a [' + lcFileName + '] porque el archivo estaba en uso o no se puede acceder a el.' + ENDIF + + lcMenErr = 'ERROR ' + TRANSFORM(loEx.ERRORNO) + ', ' + loEx.MESSAGE + CHR(13) ; + + loEx.PROCEDURE + ', line ' + TRANSFORM(loEx.LINENO) + CHR(13) ; + + loEx.LINECONTENTS + + IF TRANSFORM(tcDontShowErrors) # '1' THEN + MESSAGEBOX( lcMenErr, 0+16+4096, 'ATENCIÓN!! Ha ocurrido un error al capitalizar', 600000 ) + ENDIF + ENDIF + + FINALLY + loFSO = NULL + tcFileName = lcFileName + + *-- Si existe FileName_Caps.LOG, lo actualiza + IF FILE(lcLogFile) + IF NOT EMPTY(lcMenErr) + tcLog = tcLog + CR_LF + CR_LF + lcMenErr + ENDIF + + STRTOFILE( tcLog, lcLogFile, 1 ) + ENDIF + + ENDTRY + + RETURN lcFileName + ENDPROC + +ENDDEFINE && CLASS cl_FileName_Caps AS Custom diff --git a/FoxBin2PRGVersionFile.txt b/FoxBin2PRGVersionFile.txt index a9275e1..7e20099 100644 --- a/FoxBin2PRGVersionFile.txt +++ b/FoxBin2PRGVersionFile.txt @@ -2,8 +2,8 @@ Lparameters toUpdateInfo Local lcNote With toUpdateInfo - .VersionNumber = 'v1.19.46' - .VersionDate = Date(2016,02,06) + .VersionNumber = 'v1.19.47' + .VersionDate = Date(2016,06,08) .SourceFileUrl = 'http://vfpxrepository.com/dl/thorupdate/Projects/FoxBin2Prg/FoxBin2Prg.Zip' .Link = 'http://vfpx.codeplex.com/wikipage?title=FoxBin2PRG' @@ -17,6 +17,15 @@ Demo video using FoxBin2Prg with PlasticSCM: http://youtu.be/sE4wQ50Itqg Change History ------------------------------------------------------------- +2016/06/08 v1.19.47 +- Bug Fix: When a filename "*" is specified with a type "*", an automatic regeneration of all binary files is made from text files (Alejandro Sosa) +- BugFix: Added variable declaration (Doug Hennig) +- BugFix: Fixed incorrectly named variable (Doug Hennig) +- BugFix: Added missing assignment (Doug Hennig) +- Enhancement: Put double quotes around path in case in contains single quote (Doug Hennig) +- BugFix: Added "+16" to Debug flags to maintain internal defaults to not generate timestamps on xx2 files +- Feature: Added support for appending data from DB2 to DBF with the new value DBF_Conversion_Support=8. All datatypes except General. (Walter Nicholls) + 2016/02/06 v1.19.46 - Bug Fix: set_UserValue() method causes error when trying to get information about another error and the VFP binary table can not be opened (ie, because corrupted memo) - Feature: Added internal support for querying directory cfg information, with a new optional parameter, for API methods that require it (ie: get_Ext2FromExt, hasSupport*) diff --git a/TESTS/DATOS_READONLY/fb2p_free.cdx b/TESTS/DATOS_READONLY/fb2p_free.cdx index b5004ca..8857e9b 100644 Binary files a/TESTS/DATOS_READONLY/fb2p_free.cdx and b/TESTS/DATOS_READONLY/fb2p_free.cdx differ diff --git a/TESTS/DATOS_READONLY/FB2P_FREE.DB2 b/TESTS/DATOS_READONLY/fb2p_free.db2 similarity index 74% rename from TESTS/DATOS_READONLY/FB2P_FREE.DB2 rename to TESTS/DATOS_READONLY/fb2p_free.db2 index df554e5..3a8659c 100644 --- a/TESTS/DATOS_READONLY/FB2P_FREE.DB2 +++ b/TESTS/DATOS_READONLY/fb2p_free.db2 @@ -8,7 +8,7 @@ 1252 - 2013/12/12 + 0x00000032Visual FoxPro, Varchar, Varbinary, or Blob-enabled @@ -371,7 +371,7 @@ - 30 + 505 @@ -381,12 +381,12 @@ - LOGICO - BINARY - LOGICO - + CARACTER + CANDIDATE + CARACTER + .NOT.EMPTY(caracter) ASCENDING - MACHINE + GENERAL ENTERO @@ -397,13 +397,93 @@ MACHINE - CARACTER - CANDIDATE - CARACTER - .NOT.EMPTY(caracter) + LOGICO + BINARY + LOGICO + ASCENDING - GENERAL + MACHINE + + + + + / / + / / : : + .F. + 0.00000 + 0.000000 + 0.000 + + 0.0000 + 0 + + + + + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg + + 45 + + + axaxaxaxaXAXA + 1969/11/26 + 1969/11/26 22:10:06 + .T. + 123.45676 + 123.456786 + 123.456 + NgAuAEUAcwB0AGEAIABlAHMAIAB1AG4AYQAgAGYAcgBhAHMAZQAgAGMAbwBkAGkAZgBpAGMAYQBkAGEAIABlAG4AIABoAGUAeABhACAAeQAgAGMAbwBuACAAYwBhAHIAYQBjAHQAZQByAGUAcwAgAGUAcwBwAGUAYwBpAGEAbABlAHMALgAgAOEA6QDtAPMA+gDBAMkAzQDTANoAxADLAM8A1gDcAOQA6wDvAPYA/ADgAOgA7ADyAPkA8QDRAMcA5wBeAA== + 12345.6786 + 1234567896 + 6.notas TXT. áéíóúÄËÏÖÜÑñäëïöü. ^FinÇç + Ni5GcmFzZSBVVEYtOC4gw6HDqcOtw7PDusOEw4vDj8OWw5w= + var char 6.áéíóúÜÑ + yQBzAHQAYQAgAGUAcwAgAGwAYQAgAHMAZQDxAGEAbAAhAA== + Q2hhckJpbi02LsOhw6nDrcOzw7rDnMORICAgICAg + VkNoYXJCaW4tNi7DocOpw63Ds8O6w5zDkQ== + 35 + + + lalal.áéíóúÜÑ + 1969/11/27 + 1969/11/27 22:10:07 + .T. + 123.45677 + 123.456787 + 123.457 + NwAuAEUAcwB0AGEAIABlAHMAIAB1AG4AYQAgAGYAcgBhAHMAZQAgAGMAbwBkAGkAZgBpAGMAYQBkAGEAIABlAG4AIABoAGUAeABhACAAeQAgAGMAbwBuACAAYwBhAHIAYQBjAHQAZQByAGUAcwAgAGUAcwBwAGUAYwBpAGEAbABlAHMALgAgAOEA6QDtAPMA+gDBAMkAzQDTANoAxADLAM8A1gDcAOQA6wDvAPYA/ADgAOgA7ADyAPkA8QDRAMcA5wBeAA== + 12345.6787 + 1234567897 + 7.notas TXT. áéíóúÄËÏÖÜÑñäëïöü. ^FinÇç + Ny5GcmFzZSBVVEYtOC4gw6HDqcOtw7PDusOEw4vDj8OWw5w= + var char 7.áéíóúÜÑ + yQB4AGkAdABvAHMAIADaAG4AaQBjAG8AcwAhACAAOgApAA== + Q2hhckJpbi03LsOhw6nDrcOzw7rDnMORICAgICAg + VkNoYXJCaW4tNy7DocOpw63Ds8O6w5zDkQ== + 30 + + + pepepepepEPE + 1969/11/25 + 1969/11/25 22:10:05 + .T. + 123.45675 + 123.456785 + 123.455 + NQAuAEUAcwB0AGEAIABlAHMAIAB1AG4AYQAgAGYAcgBhAHMAZQAgAGMAbwBkAGkAZgBpAGMAYQBkAGEAIABlAG4AIABoAGUAeABhACAAeQAgAGMAbwBuACAAYwBhAHIAYQBjAHQAZQByAGUAcwAgAGUAcwBwAGUAYwBpAGEAbABlAHMALgAgAOEA6QDtAPMA+gDBAMkAzQDTANoAxADLAM8A1gDcAOQA6wDvAPYA/ADgAOgA7ADyAPkA8QDRAMcA5wBeAA== + 12345.6785 + 1234567895 + 5.notas TXT. áéíóúÄËÏÖÜÑñäëïöü. ^FinÇç + NS5GcmFzZSBVVEYtOC4gw6HDqcOtw7PDusOEw4vDj8OWw5w= + var char 5.áéíóúÜÑ + yQBzAHQAYQAgAGUAcwAgAGwAYQAgAHMAZQDxAGEAbAAhAA== + Q2hhckJpbi01LsOhw6nDrcOzw7rDnMORICAgICAg + VkNoYXJCaW4tNS7DocOpw63Ds8O6w5zDkQ== + 40 + + +
diff --git a/TESTS/DATOS_READONLY/fb2p_free.dbf b/TESTS/DATOS_READONLY/fb2p_free.dbf index 72cf766..e166f21 100644 Binary files a/TESTS/DATOS_READONLY/fb2p_free.dbf and b/TESTS/DATOS_READONLY/fb2p_free.dbf differ diff --git a/TESTS/DATOS_READONLY/fb2p_free.dbf.cfg b/TESTS/DATOS_READONLY/fb2p_free.dbf.cfg new file mode 100644 index 0000000..2b5580f --- /dev/null +++ b/TESTS/DATOS_READONLY/fb2p_free.dbf.cfg @@ -0,0 +1,3 @@ +DBF_Conversion_Support: 8 +DBF_Conversion_Order: caracter +DBF_Conversion_Condition: .T. \ No newline at end of file diff --git a/TESTS/DATOS_READONLY/fb2p_free.fpt b/TESTS/DATOS_READONLY/fb2p_free.fpt index 601fa8d..06c9492 100644 Binary files a/TESTS/DATOS_READONLY/fb2p_free.fpt and b/TESTS/DATOS_READONLY/fb2p_free.fpt differ diff --git a/TESTS/ft__foxbin2prg__c_conversor_prg_a_dbf.prg b/TESTS/ft__foxbin2prg__c_conversor_prg_a_dbf.prg index 061c156..f17280c 100644 --- a/TESTS/ft__foxbin2prg__c_conversor_prg_a_dbf.prg +++ b/TESTS/ft__foxbin2prg__c_conversor_prg_a_dbf.prg @@ -286,9 +286,16 @@ DEFINE CLASS ft__foxbin2prg__c_conversor_prg_a_dbf AS FxuTestCase OF FxuTestCase this.assertequals( lnFields_OUT, lnFields_IN, '[Cantidad de campos IN y OUT]' ) FOR I = 1 TO lnFields_IN - FOR X = 1 TO 18 - THIS.assertequals( laCampos_IN(I,X), laCampos_OUT(I,X), '[Comparando estructura del campo ' + laCampos_IN(I,1) + ']' ) - ENDFOR + IF laCampos_IN(I,18) > 0 && Autoinc_Step + *-- Para los campos AutoInc solo se comparan los primeros 4 datos de estructura + FOR X = 1 TO 4 + THIS.assertequals( laCampos_IN(I,X), laCampos_OUT(I,X), '[Comparando estructura del campo ' + laCampos_IN(I,1) + ']' ) + ENDFOR + ELSE + FOR X = 1 TO 18 + THIS.assertequals( laCampos_IN(I,X), laCampos_OUT(I,X), '[Comparando estructura del campo ' + laCampos_IN(I,1) + ']' ) + ENDFOR + ENDIF ENDFOR CATCH TO loEx diff --git a/foxbin2prg.cfg.txt b/foxbin2prg.cfg.txt index da907ad..338f943 100644 --- a/foxbin2prg.cfg.txt +++ b/foxbin2prg.cfg.txt @@ -1,5 +1,5 @@ **************************************************************************************************** -* FOXBIN2PRG v1.19.43 +* FOXBIN2PRG v1.19.47 * CONFIGURATION FILE / ARCHIVO DE CONFIGURACIÓN **************************************************************************************************** @@ -34,7 +34,7 @@ * LBX_Conversion_Support: 2 && 0=No support, 1=Generate TXT only (Diff), 2=Generate TXT and BIN (Merge) * MNX_Conversion_Support: 2 && 0=No support, 1=Generate TXT only (Diff), 2=Generate TXT and BIN (Merge) * DBC_Conversion_Support: 2 && 0=No support, 1=Generate TXT only (Diff), 2=Generate TXT and BIN (Merge) -* DBF_Conversion_Support: 1 && 0=No support, 1=Generate TXT only (Diff), 2=Generate TXT and BIN (Merge), 4=Generate TXT with DATA for DIFF (No Bidirectional!) +* DBF_Conversion_Support: 1 && 0=No support, 1=Generate TXT only (Diff), 2=Generate TXT and BIN (Merge/Only Structure!), 4=Generate TXT with DATA (Diff), 8=Export and Import DATA (Merge/Structure & Data) * >>DBF_Conversion_Support NOTE: >> EN: FoxBin2Prg support bi-directional convertion of DBFs, but does not keep data. Use with care. * >> ES: FoxBin2Prg tiene soporte bi-direccional para convertir DBF, pero no mantiene los datos. Usar con cuidado. * DBF_Conversion_Included: * && If DBF_Conversion_Support:4, you can specify multiple filemasks: www,fb2p_free.dbf / Si DBF_Conversion_Support:4, se pueden indicar múltiples máscaras de archivo: www,fb2p_free.dbf diff --git a/foxbin2prg.exe b/foxbin2prg.exe index 856974a..4f1db04 100644 Binary files a/foxbin2prg.exe and b/foxbin2prg.exe differ diff --git a/foxbin2prg.pj2 b/foxbin2prg.pj2 index 65e0f7b..190b5c3 100644 --- a/foxbin2prg.pj2 +++ b/foxbin2prg.pj2 @@ -26,7 +26,7 @@ _LegalTrademark = "Creative Commons 4: Reconocimiento - CompartirIgual (by-sa): _ProductName = "FOXBIN2PRG" _MajorVer = "1" _MinorVer = "19" -_Revision = "46" +_Revision = "47" _LanguageID = "1034" _AutoIncrement = "0" * diff --git a/foxbin2prg.pjt b/foxbin2prg.pjt index 1752025..fec17fc 100644 Binary files a/foxbin2prg.pjt and b/foxbin2prg.pjt differ diff --git a/foxbin2prg.pjx b/foxbin2prg.pjx index ed05983..7254432 100644 Binary files a/foxbin2prg.pjx and b/foxbin2prg.pjx differ diff --git a/foxbin2prg.prg b/foxbin2prg.prg index 7877070..08d52eb 100644 --- a/foxbin2prg.prg +++ b/foxbin2prg.prg @@ -182,6 +182,8 @@ * 25/11/2015 FDBOZZO v1.19.46 Bug Fix Pj2: Se genera un error al regenerar un PJX desde un PJ2 donde algún archivo contiene paréntesis (EddieC) * 25/11/2015 FDBOZZO v1.19.46 Mejora dbf: Nuevo parámetro ExcludeDBFAutoincNextval para evitar diferencias por este dato (edyshor) * 04/02/2016 FDBOZZO v1.19.46 Bug Fix: Cuando se procesa un archivo en el directorio raiz, se genera un error 2062 (Aurélien Dellieux) +* 10/02/2016 FDBOZZO v1.19.47 Bug Fix: Cuando se indica como nombre de archivo "*" y como tipo "*", se regeneran automáticamente todos los archivos binarios desde los archivos de texto (Alejandro Sosa) +* 25/05/2016 FDBOZZO v1.19.47 Mejora DBF-Data: Permitir importar datos de los DB2 a los DBF con el nuevo valor DBF_Conversion_Support=8. Todos los tipos de datos excepto General. (Walter Nicholls) * * *--------------------------------------------------------------------------------------------------- @@ -282,6 +284,7 @@ * 20/11/2015 EddieC Reporte bug Pjx v1.19.45: Se genera un error al regenerar un PJX desde un PJ2 donde algún archivo contiene paréntesis (Arreglado en v1.19.46 Preview-9) * 24/11/2015 edyshor Mejora dbf v1.19.45: Nuevo parámetro ExcludeDBFAutoincNextval para evitar diferencias por este dato (Agregado en v1.19.46 Preview-9) * 01/02/2016 Aurélien Dellieux Reporte bug v1.19.45: Cuando se procesa un archivo en el directorio raiz, se genera un error 2062 (Arreglado en v1.19.46 Preview-10) +* 10/02/2016 Alejandro Sosa Reporte bug v1.19.46: Cuando se indica como nombre de archivo "*" y como tipo "*", se regeneran automáticamente todos los archivos binarios desde los archivos de texto (Arreglado en v1.19.47 Preview-1) * * *--------------------------------------------------------------------------------------------------- @@ -459,7 +462,7 @@ LPARAMETERS tc_InputFile, tcType, tcTextName, tlGenText, tcDontShowErrors, tcDeb *** DH 06/02/2014: added additional constants #DEFINE C_RECORDS_I '' #DEFINE C_RECORDS_F '' -#DEFINE C_RECORD_I '' && *** FDBOZZO 2014/07/15: Optimized RECORD tag adding num property to not use REGNUM field +#DEFINE C_RECORD_I '' && *** FDBOZZO 2016/06/06: Quitado el REGNUM para evitar diferencias innecesarias #DEFINE C_RECORD_F '' #DEFINE C_RECNO_I '' #DEFINE C_RECNO_F '' @@ -796,7 +799,8 @@ DEFINE CLASS c_foxbin2prg AS Session o_Conversor = NULL o_Frm_Avance = NULL o_WSH = NULL - o_FSO = NULL + o_FSO = NULL && Scripting.FileSystemObject + o_TextStream = NULL && Scripting.TextStream o_FNC = NULL && Filename_caps object o_Configuration = NULL run_AfterCreateTable = '' @@ -2117,7 +2121,7 @@ DEFINE CLASS c_foxbin2prg AS Session CASE LEFT( laConfig(I), 23 ) == LOWER('DBF_Conversion_Support:') lcValue = ALLTRIM( SUBSTR( laConfig(I), 24 ) ) - IF INLIST( lcValue, '0', '1', '2', '4' ) THEN + IF INLIST( lcValue, '0', '1', '2', '4', '8' ) THEN lo_CFG.DBF_Conversion_Support = INT( VAL( lcValue ) ) .writeLog( C_TAB + JUSTFNAME(lcConfigFile) + ' > DBF_Conversion_Support: ' + TRANSFORM(lo_CFG.DBF_Conversion_Support) ) ENDIF @@ -2352,6 +2356,67 @@ DEFINE CLASS c_foxbin2prg AS Session ENDFUNC + PROCEDURE get_DBF_Configuration(tc_InputFile as String, to_out_DBF_CFG as Object, tlGenerateLog as Boolean) as Integer + *--------------------------------------------------------------------------------------------------- + * PARÁMETROS: (v=Pasar por valor | @=Pasar por referencia) (!=Obligatorio | ?=Opcional) (IN/OUT) + * tc_InputFile (@! IN ) Ruta al archivo con Extensión para comprobar si tiene soporte de conversión + * to_out_DBF_CFG (@? OUT) Objeto CFG del DBF indicado, con las propiedades que contenga el CFG y sus valores + * RETORNO (v? OUT) Devuelve 0 si no existe el archivo CFG y 1 si lo encuentra + *--------------------------------------------------------------------------------------------------- + #IF .F. + LOCAL to_out_DBF_CFG AS CL_DBF_CFG OF 'FOXBIN2PRG.PRG' + #ENDIF + + LOCAL lcTableCFG, lnFileCount, laDirFile(1,5), I, lcConfigItem + lcTableCFG = tc_InputFile + '.CFG' + lnFileCount = ADIR(laDirFile, lcTableCFG) + + IF lnFileCount = 1 + to_out_DBF_CFG = CREATEOBJECT("CL_DBF_CFG") + + IF tlGenerateLog THEN + THIS.writeLog() + THIS.writeLog(' > Found DBF configuration file: ' + lcTableCFG) + ENDIF + + FOR I = 1 TO ALINES( laConfig, FILETOSTR( lcTableCFG ), 1+4 ) + lcConfigItem = LOWER( laConfig(I) ) + + DO CASE + CASE INLIST( LEFT( lcConfigItem, 1 ), '*', '#', '/', "'" ) + LOOP + + CASE LEFT( lcConfigItem, 21 ) == LOWER('DBF_Conversion_Order:') + to_out_DBF_CFG.DBF_Conversion_Order = ALLTRIM( SUBSTR( laConfig(I), 22 ) ) + IF tlGenerateLog THEN + THIS.writeLog(' ' + JUSTFNAME(lcTableCFG) + ' > DBF_Conversion_Order: ' + to_out_DBF_CFG.DBF_Conversion_Order ) + ENDIF + + CASE LEFT( lcConfigItem, 25 ) == LOWER('DBF_Conversion_Condition:') + to_out_DBF_CFG.DBF_Conversion_Condition = ALLTRIM( SUBSTR( laConfig(I), 26 ) ) + IF tlGenerateLog THEN + THIS.writeLog(' ' + JUSTFNAME(lcTableCFG) + ' > DBF_Conversion_Condition: ' + to_out_DBF_CFG.DBF_Conversion_Condition ) + ENDIF + + CASE LEFT( lcConfigItem, 23 ) == LOWER('DBF_Conversion_Support:') + to_out_DBF_CFG.DBF_Conversion_Support = INT( VAL( SUBSTR( laConfig(I), 24 ) ) ) + IF tlGenerateLog THEN + THIS.writeLog(' ' + JUSTFNAME(lcTableCFG) + ' > DBF_Conversion_Support: ' + TRANSFORM(to_out_DBF_CFG.DBF_Conversion_Support) ) + ENDIF + + ENDCASE + ENDFOR + + IF tlGenerateLog THEN + THIS.writeLog() + ENDIF + + ENDIF + + RETURN lnFileCount + ENDPROC + + PROCEDURE get_Ext2FromExt *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (v=Pasar por valor | @=Pasar por referencia) (!=Obligatorio | ?=Opcional) (IN/OUT) @@ -2385,72 +2450,135 @@ DEFINE CLASS c_foxbin2prg AS Session ENDPROC - PROCEDURE hasSupport_Bin2Prg + PROCEDURE hasSupport_Bin2Prg(tcFileName as String, tcDir as String) as Boolean *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (v=Pasar por valor | @=Pasar por referencia) (!=Obligatorio | ?=Opcional) (IN/OUT) - * tcExt (@! IN ) Extensión para comprobar si tiene soporte de conversión + * tcFilename (@! IN ) Extensión para comprobar si el archivo tiene soporte de conversión * tcDir (@? IN ) Directorio del que devolver su configuración * RETORNO (v? OUT) .T. si tiene soporte de conversión, .F. si no lo tiene *--------------------------------------------------------------------------------------------------- - LPARAMETERS tcExt, tcDir - - LOCAL llhasSupport - tcExt = UPPER(JUSTEXT('.' + tcExt)) + LOCAL llhasSupport, lcExt, lcDir ; + , loDBF_CFG AS CL_DBF_CFG OF 'FOXBIN2PRG.PRG' WITH THIS AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' - IF NOT EMPTY(tcDir) - .evaluateConfiguration( '', '', '', '', '', '', '', '', tcDir, 'D' ) + loDBF_CFG = NULL + lcExt = UPPER(JUSTEXT('.' + tcFileName)) + + IF '\' $ tcFileName AND lcExt == 'DBF' THEN + lcDir = JUSTPATH(tcFileName) + .get_DBF_Configuration(tcFileName, @loDBF_CFG) + ELSE + lcDir = tcDir ENDIF - llhasSupport = ICASE( tcExt == 'PJX', .PJX_Conversion_Support > 0 ; - , tcExt == 'VCX', .VCX_Conversion_Support > 0 ; - , tcExt == 'SCX', .SCX_Conversion_Support > 0 ; - , tcExt == 'FRX', .FRX_Conversion_Support > 0 ; - , tcExt == 'LBX', .LBX_Conversion_Support > 0 ; - , tcExt == 'MNX', .MNX_Conversion_Support > 0 ; - , tcExt == 'DBF', .DBF_Conversion_Support > 0 ; - , tcExt == 'DBC', .DBC_Conversion_Support > 0 ; + IF NOT EMPTY(lcDir) + .evaluateConfiguration( '', '', '', '', '', '', '', '', lcDir, 'D' ) + ENDIF + + llhasSupport = ICASE( lcExt == 'PJX', .PJX_Conversion_Support > 0 ; + , lcExt == 'VCX', .VCX_Conversion_Support > 0 ; + , lcExt == 'SCX', .SCX_Conversion_Support > 0 ; + , lcExt == 'FRX', .FRX_Conversion_Support > 0 ; + , lcExt == 'LBX', .LBX_Conversion_Support > 0 ; + , lcExt == 'MNX', .MNX_Conversion_Support > 0 ; + , lcExt == 'DBF', .DBF_Conversion_Support > 0 OR NOT ISNULL(loDBF_CFG) ; + , lcExt == 'DBC', .DBC_Conversion_Support > 0 ; , .F. ) ENDWITH && THIS - RELEASE tcExt RETURN llhasSupport ENDPROC - PROCEDURE hasSupport_Prg2Bin + PROCEDURE hasSupport_Prg2Bin(tcFileName as String, tcDir as String) as Boolean *--------------------------------------------------------------------------------------------------- * PARÁMETROS: (v=Pasar por valor | @=Pasar por referencia) (!=Obligatorio | ?=Opcional) (IN/OUT) - * tcExt (@! IN ) Extensión para comprobar si tiene soporte de conversión + * tcFilename (@! IN ) Extensión para comprobar si el archivo tiene soporte de conversión * tcDir (@? IN ) Directorio del que devolver su configuración * RETORNO (v? OUT) .T. si tiene soporte de conversión, .F. si no lo tiene *--------------------------------------------------------------------------------------------------- - LPARAMETERS tcExt, tcDir - - LOCAL llhasSupport - tcExt = UPPER(JUSTEXT('.' + tcExt)) + LOCAL llhasSupport, lcExt, lcDir ; + , loDBF_CFG AS CL_DBF_CFG OF 'FOXBIN2PRG.PRG' WITH THIS AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' - IF NOT EMPTY(tcDir) - .evaluateConfiguration( '', '', '', '', '', '', '', '', tcDir, 'D' ) + loDBF_CFG = NULL + lcExt = UPPER(JUSTEXT('.' + tcFileName)) + + IF '\' $ tcFileName AND lcExt == .c_DB2 THEN + lcDir = JUSTPATH(tcFileName) + .get_DBF_Configuration(tcFileName, @loDBF_CFG) + ELSE + lcDir = tcDir ENDIF - llhasSupport = ICASE( tcExt == .c_PJ2, .PJX_Conversion_Support = 2 ; - , tcExt == .c_VC2, .VCX_Conversion_Support = 2 ; - , tcExt == .c_SC2, .SCX_Conversion_Support = 2 ; - , tcExt == .c_FR2, .FRX_Conversion_Support = 2 ; - , tcExt == .c_LB2, .LBX_Conversion_Support = 2 ; - , tcExt == .c_MN2, .MNX_Conversion_Support = 2 ; - , tcExt == .c_DB2, .DBF_Conversion_Support = 2 ; - , tcExt == .c_DC2, .DBC_Conversion_Support = 2 ; + IF NOT EMPTY(lcDir) + .evaluateConfiguration( '', '', '', '', '', '', '', '', lcDir, 'D' ) + ENDIF + + llhasSupport = ICASE( lcExt == .c_PJ2, .PJX_Conversion_Support = 2 ; + , lcExt == .c_VC2, .VCX_Conversion_Support = 2 ; + , lcExt == .c_SC2, .SCX_Conversion_Support = 2 ; + , lcExt == .c_FR2, .FRX_Conversion_Support = 2 ; + , lcExt == .c_LB2, .LBX_Conversion_Support = 2 ; + , lcExt == .c_MN2, .MNX_Conversion_Support = 2 ; + , lcExt == .c_DB2, INLIST(.DBF_Conversion_Support, 2, 8) OR NOT ISNULL(loDBF_CFG) AND loDBF_CFG.DBF_Conversion_Support = 8 ; + , lcExt == .c_DC2, .DBC_Conversion_Support = 2 ; , .F. ) ENDWITH && THIS - RELEASE tcExt RETURN llhasSupport ENDPROC + PROCEDURE conversionSupportType(tcFileName as String, tlGenerarLog as Boolean) as Integer + *--------------------------------------------------------------------------------------------------- + * PARÁMETROS: (v=Pasar por valor | @=Pasar por referencia) (!=Obligatorio | ?=Opcional) (IN/OUT) + * tcFilename (@! IN ) Extensión para comprobar si el archivo tiene soporte de conversión + * RETORNO (v? OUT) Devuelve el código de soporte + *--------------------------------------------------------------------------------------------------- + LOCAL lnSupportType, lcExt, lcDir, lcFilename ; + , loDBF_CFG AS CL_DBF_CFG OF 'FOXBIN2PRG.PRG' + + TRY + WITH THIS AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' + loDBF_CFG = NULL + lcExt = UPPER(JUSTEXT('.' + tcFileName)) + + IF '\' $ tcFileName AND INLIST(lcExt, .c_DB2, 'DBF') THEN + lcFilename = FORCEEXT(tcFileName, 'DBF') + lcDir = JUSTPATH(lcFilename) + .get_DBF_Configuration(lcFilename, @loDBF_CFG, tlGenerarLog) + ELSE + lcDir = SYS(5) + CURDIR() + ENDIF + + IF NOT EMPTY(lcDir) + .evaluateConfiguration( '', '', '', '', '', '', '', '', lcDir, 'D' ) + ENDIF + + lnSupportType = ICASE( ; + INLIST(lcExt, .c_PJ2, 'PJX'), .PJX_Conversion_Support ; + , INLIST(lcExt, .c_VC2, 'VCX'), .VCX_Conversion_Support ; + , INLIST(lcExt, .c_SC2, 'SCX'), .SCX_Conversion_Support ; + , INLIST(lcExt, .c_FR2, 'FRX'), .FRX_Conversion_Support ; + , INLIST(lcExt, .c_LB2, 'LBX'), .LBX_Conversion_Support ; + , INLIST(lcExt, .c_MN2, 'MNX'), .MNX_Conversion_Support ; + , INLIST(lcExt, .c_DB2, 'DBF'), ICASE( ISNULL(loDBF_CFG) OR loDBF_CFG.DBF_Conversion_Support = 0, .DBF_Conversion_Support, loDBF_CFG.DBF_Conversion_Support ) ; + , INLIST(lcExt, .c_DC2, 'DBC'), .DBC_Conversion_Support ; + , 0 ) + + lnSupportType = INT(lnSupportType) + ENDWITH && THIS + + FINALLY + STORE NULL TO loDBF_CFG + RELEASE loDBF_CFG + ENDTRY + + RETURN lnSupportType + ENDPROC + + PROCEDURE execute *-------------------------------------------------------------------------------------------------------------- * PARÁMETROS: (v=Pasar por valor | @=Pasar por referencia) (!=Obligatorio | ?=Opcional) (IN/OUT) @@ -2764,6 +2892,10 @@ DEFINE CLASS c_foxbin2prg AS Session ENDCASE ENDIF + CASE EMPTY( JUSTEXT( EVL(tc_InputFile,'') ) ) + *-- NO SE INDICÓ NINGUNA EXTENSIÓN + ERROR loLang.C_INVALID_PARAMETER_LOC + ': cInputFile = "' + tc_InputFile + '"' + OTHERWISE *-- DEMÁS ARCHIVOS *-- Filespec: "*.EXT" @@ -3546,7 +3678,7 @@ DEFINE CLASS c_foxbin2prg AS Session .changeFileAttribute( FORCEEXT( .c_InputFile, .c_LB2 ), lcForceAttribs ) CASE lcExtension = 'DBF' - IF NOT INLIST(.DBF_Conversion_Support, 1, 2, 4) + IF NOT INLIST(.DBF_Conversion_Support, 1, 2, 4, 8) ERROR (TEXTMERGE(loLang.C_FILE_NAME_IS_NOT_SUPPORTED_LOC)) ENDIF .c_OutputFile = FORCEEXT( .c_InputFile, .c_DB2 ) @@ -3615,7 +3747,9 @@ DEFINE CLASS c_foxbin2prg AS Session .changeFileAttribute( FORCEEXT( .c_InputFile, 'LBT' ), lcForceAttribs ) CASE lcExtension = .c_DB2 - IF .DBF_Conversion_Support <> 2 + IF INLIST(.DBF_Conversion_Support, 2, 8) OR ADIR(laDirFile, FORCEEXT(.c_InputFile, 'DBF') + '.CFG') = 1 THEN + *-- Soporte txt-2-bin habilitado + ELSE ERROR (TEXTMERGE(loLang.C_FILE_NAME_IS_NOT_SUPPORTED_LOC)) ENDIF .c_OutputFile = FORCEEXT( .c_InputFile, 'DBF' ) @@ -3920,7 +4054,7 @@ DEFINE CLASS c_foxbin2prg AS Session *-- Verifico si el carácter es un separador de cadenas: '"[ X = AT( SUBSTR(lcStr, I, 1), lcSeparadoresIzq) - + IF X > 0 THEN lnAT1 = AT(laSeparador(X,1), lcStr) ENDIF @@ -4582,7 +4716,7 @@ DEFINE CLASS c_foxbin2prg AS Session ENDPROC - FUNCTION WScriptShell_Run + FUNCTION wscriptshell_run * Modificación basada en la rutina RunExitCode.prg de William GC Steinford (nov 2002) * pero compatible con el método Run de WScript.Shell para su reemplazo cuando no es posible usarlo. * http://fox.wikis.com/wc.dll?Wiki~ProcessExitCode @@ -4730,8 +4864,8 @@ DEFINE CLASS c_foxbin2prg AS Session * HKEY hkeyClass; 4 * DWORD dwHotKey; 4 * union { - * HANDLE hIcon; - * HANDLE hMonitor; + * HANDLE hIcon; + * HANDLE hMonitor; * } DUMMYUNIONNAME; 4 * HANDLE hProcess; 4 *} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO; @@ -4772,7 +4906,7 @@ DEFINE CLASS c_foxbin2prg AS Session * TerminateProcess(ln_hProcess, 0) *ENDIF ENDIF - + ELSE IF tlDebug ? "Could not create process" @@ -6387,7 +6521,7 @@ DEFINE CLASS c_conversor_base AS Custom *-- Verifico si el carácter es un separador de cadenas: '"[ X = AT( SUBSTR(lcStr, I, 1), lcSeparadoresIzq) - + IF X > 0 THEN lnAT1 = AT(laSeparador(X,1), lcStr) ENDIF @@ -11688,9 +11822,9 @@ DEFINE CLASS c_conversor_prg_a_frx AS c_conversor_prg_a_bin IF C_DATA_F $ tcLine && Fin del valor lcValue = lcValue + CR_LF + STREXTRACT( tcLine, '', C_DATA_F ) - + *-- Ajustes: En los labels, no se usa CR+LF, sino que se usa solo CR - IF toReg.objType = "5" THEN + IF toReg.ObjType = "5" THEN lcValue = STRTRAN(lcValue, CR_LF, C_CR) ENDIF @@ -11880,6 +12014,8 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin + [] ; + [] ; + [] ; + + [] ; + + [] ; + [] c_Type = 'DB2' @@ -11901,7 +12037,9 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin TRY LOCAL lnCodError, loEx AS EXCEPTION, laCodeLines(1), lnCodeLines, laLineasExclusion(1), lnBloquesExclusion, I ; - , lnIDInputFile + , lnIDInputFile, lnFileCount, laConfig(1), lcConfigItem, lc_DBF_Conversion_Support, lcAlterTable ; + , lcTempDBC, llImportData ; + , loDBF_CFG AS CL_DBF_CFG OF 'FOXBIN2PRG.PRG' STORE 0 TO lnCodError, lnCodeLines WITH THIS AS c_conversor_prg_a_dbf OF 'FOXBIN2PRG.PRG' @@ -11916,12 +12054,23 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin EXIT && Si se indicó no procesar, se sale aquí. (Modo de simulación) ENDIF + *-- If table CFG exists, use it for DBF-specific configuration. FDBOZZO. 2014/06/15 + lnFileCount = toFoxBin2Prg.get_DBF_Configuration( FORCEEXT(.c_InputFile, 'DBF'), @loDBF_CFG, .T. ) + lcTempDBC = FORCEPATH( '_FB2P', JUSTPATH(.c_OutputFile) ) + + DO CASE + CASE toFoxBin2Prg.DBF_Conversion_Support = 8 && TXT2BIN (DATA IMPORT) + llImportData = .T. + CASE INLIST(toFoxBin2Prg.DBF_Conversion_Support, 1, 2, 4) AND lnFileCount = 1 + llImportData = (loDBF_CFG.DBF_Conversion_Support = 8) + ENDCASE + C_FB2PRG_CODE = FILETOSTR( .c_InputFile ) lnCodeLines = ALINES( laCodeLines, C_FB2PRG_CODE ) toFoxBin2Prg.doBackup( .F., .T., '', '', '' ) - *-- Identifico el inicio/fin de bloque, definición, cabecera y cuerpo del reporte + *-- Identifico el inicio/fin de bloque, campos e índices de la tabla .identifyCodeBlocks( @laCodeLines, lnCodeLines, @laLineasExclusion, lnBloquesExclusion, @toTable ) DO CASE @@ -11937,7 +12086,20 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin ENDIF toFoxBin2Prg.updateProcessedFile( lnIDInputFile ) - .writeBinaryFile( @toTable, @toFoxBin2Prg ) + .writeBinaryFile_STRUCTURE( @toTable, @toFoxBin2Prg, @lcAlterTable ) + + IF llImportData AND lnCodeLines > 1 AND toTable._I > 1 THEN + *-- Identifico los registros de la tabla y los agrego + I = toTable._I - 1 + toTable.analyzeCodeBlock( C_TABLE_I, @laCodeLines, @I, lnCodeLines, @toFoxBin2Prg ) + ENDIF + + IF NOT EMPTY(lcAlterTable) + EXECSCRIPT(lcAlterTable) + ENDIF + + .writeBinaryFile_INDEXES( @toTable, @toFoxBin2Prg ) + ENDWITH && THIS @@ -11952,6 +12114,18 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin FINALLY USE IN (SELECT("TABLABIN")) + USE IN (SELECT(JUSTSTEM(THIS.c_OutputFile))) + + IF NOT EMPTY(lcTempDBC) + CLOSE DATABASES + ERASE (FORCEEXT(lcTempDBC,'DBC')) + ERASE (FORCEEXT(lcTempDBC,'DCT')) + ERASE (FORCEEXT(lcTempDBC,'DCX')) + ENDIF + + STORE NULL TO loDBF_CFG + RELEASE loDBF_CFG + ENDTRY RETURN lnCodError @@ -11959,8 +12133,8 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin - PROCEDURE writeBinaryFile - LPARAMETERS toTable, toFoxBin2Prg + PROCEDURE writeBinaryFile_STRUCTURE + LPARAMETERS toTable, toFoxBin2Prg, tcAlterTable *-- ----------------------------------------------------------------------------------------------------------- #IF .F. LOCAL toTable AS CL_DBF_TABLE OF 'FOXBIN2PRG.PRG' @@ -11970,16 +12144,15 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin TRY LOCAL I, lnCodError, loEx AS EXCEPTION ; , loField AS CL_DBF_FIELD OF 'FOXBIN2PRG.PRG' ; - , loIndex AS CL_DBF_INDEX OF 'FOXBIN2PRG.PRG' ; , loDBFUtils AS CL_DBF_UTILS OF 'FOXBIN2PRG.PRG' ; - , lcCreateTable, lcLongDec, lcFieldDef, lcIndex, ldLastUpdate, lcTempDBC, lnDataSessionID, lnSelect + , lcCreateTable, lcLongDec, lcFieldDef, lcIndex, lcTempDBC, lnDataSessionID, lnSelect WITH THIS AS c_conversor_prg_a_dbf OF 'FOXBIN2PRG.PRG' STORE NULL TO loField, loIndex, loDBFUtils loDBFUtils = CREATEOBJECT('CL_DBF_UTILS') STORE 0 TO lnCodError - STORE '' TO lcIndex, lcFieldDef + STORE '' TO lcIndex, lcFieldDef, tcAlterTable lnDataSessionID = toFoxBin2Prg.DATASESSIONID *-- addProcessedFile( tcFile, tcInOutType, tcProcessed, tcHasErrors, tcSupported, tcExpanded ) @@ -11995,19 +12168,25 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin ERASE (FORCEEXT(.c_OutputFile, 'CDX')) IF EMPTY(toTable._Database) - lcCreateTable = 'CREATE TABLE "' + .c_OutputFile + '" FREE CodePage=' + toTable._CodePage + ' (' + lcCreateTable = 'CREATE TABLE "' + .c_OutputFile + '" FREE CodePage=' + toTable._CodePage + ' ;' + CR_LF + ' (' ELSE lcTempDBC = FORCEPATH( '_FB2P', JUSTPATH(.c_OutputFile) ) CREATE DATABASE ( lcTempDBC ) - lcCreateTable = 'CREATE TABLE "' + .c_OutputFile + '" CodePage=' + toTable._CodePage + ' (' + lcCreateTable = 'CREATE TABLE "' + .c_OutputFile + '" CodePage=' + toTable._CodePage + ' ;' + CR_LF + ' (' ENDIF + toTable._TableName = .c_OutputFile + *-- Conformo los campos FOR EACH loField IN toTable._Fields FOXOBJECT lcLongDec = '' + IF NOT EMPTY(lcFieldDef) + lcFieldDef = lcFieldDef + ';' + CR_LF + ', ' + ENDIF + *-- Nombre, Tipo - lcFieldDef = lcFieldDef + ', ' + loField._Name + ' ' + loField._Type + lcFieldDef = lcFieldDef + loField._Name + ' ' + loField._Type *-- Longitud IF INLIST( loField._Type, 'C', 'N', 'F', 'Q', 'V' ) @@ -12045,15 +12224,19 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin *-- of DBF with this field. lcFieldDef = lcFieldDef + ' AUTOINC NEXTVAL 1 STEP ' + loField._AutoInc_Step ELSE - lcFieldDef = lcFieldDef + ' AUTOINC NEXTVAL ' + loField._AutoInc_NextVal + ' STEP ' + loField._AutoInc_Step + tcAlterTable = tcAlterTable + ' ;' + CR_LF + ' ALTER ' + loField._Name + ' ' + loField._Type + ' AUTOINC NEXTVAL ' + loField._AutoInc_NextVal + ' STEP ' + loField._AutoInc_Step ENDIF ENDIF loField = NULL ENDFOR - lcCreateTable = lcCreateTable + SUBSTR(lcFieldDef,3) + ')' - &lcCreateTable. + lcCreateTable = lcCreateTable + lcFieldDef + ')' + EXECSCRIPT(lcCreateTable) + + IF NOT EMPTY(tcAlterTable) + tcAlterTable = 'ALTER TABLE "' + .c_OutputFile + '" ' + tcAlterTable + ENDIF *-- Hook para permitir ejecución externa (por ejemplo, para rellenar la tabla con datos) IF NOT EMPTY(toFoxBin2Prg.run_AfterCreateTable) @@ -12063,6 +12246,53 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin SELECT (lnSelect) ENDIF + ENDWITH && THIS + + + CATCH TO loEx + lnCodError = loEx.ERRORNO + toFoxBin2Prg.updateProcessedFile( 0, '', '', 'E1' ) + loEx.USERVALUE = 'lcFieldDef="' + TRANSFORM(lcFieldDef) + '"' + CR_LF ; + + 'lcCreateTable="' + TRANSFORM(lcCreateTable) + '"' + + IF THIS.n_Debug > 0 AND _VFP.STARTMODE = 0 + SET STEP ON + ENDIF + + THROW + + FINALLY + STORE NULL TO loField, loDBFUtils + RELEASE I, loField, loDBFUtils ; + , lcCreateTable, lcLongDec, lcFieldDef, lcTempDBC, lnDataSessionID, lnSelect + + ENDTRY + + RETURN lnCodError + ENDPROC + + + + PROCEDURE writeBinaryFile_INDEXES + LPARAMETERS toTable, toFoxBin2Prg + *-- ----------------------------------------------------------------------------------------------------------- + #IF .F. + LOCAL toTable AS CL_DBF_TABLE OF 'FOXBIN2PRG.PRG' + LOCAL toFoxBin2Prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' + #ENDIF + + TRY + LOCAL I, lnCodError, loEx AS EXCEPTION ; + , loIndex AS CL_DBF_INDEX OF 'FOXBIN2PRG.PRG' ; + , loDBFUtils AS CL_DBF_UTILS OF 'FOXBIN2PRG.PRG' ; + , ldLastUpdate + + WITH THIS AS c_conversor_prg_a_dbf OF 'FOXBIN2PRG.PRG' + STORE NULL TO loIndex + STORE 0 TO lnCodError + STORE '' TO lcIndex + loDBFUtils = CREATEOBJECT('CL_DBF_UTILS') + *-- Regenero los índices FOR EACH loIndex IN toTable._Indexes FOXOBJECT lcIndex = 'INDEX ON ' + loIndex._Key + ' TAG ' + loIndex._TagName @@ -12106,9 +12336,7 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin CATCH TO loEx lnCodError = loEx.ERRORNO toFoxBin2Prg.updateProcessedFile( 0, '', '', 'E1' ) - loEx.USERVALUE = 'lcIndex="' + TRANSFORM(lcIndex) + '"' + CR_LF ; - + 'lcFieldDef="' + TRANSFORM(lcFieldDef) + '"' + CR_LF ; - + 'lcCreateTable="' + TRANSFORM(lcCreateTable) + '"' + loEx.USERVALUE = 'lcIndex="' + TRANSFORM(lcIndex) + '"' IF THIS.n_Debug > 0 AND _VFP.STARTMODE = 0 SET STEP ON @@ -12117,18 +12345,8 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin THROW FINALLY - USE IN (SELECT(JUSTSTEM(THIS.c_OutputFile))) - STORE NULL TO loField, loIndex, loDBFUtils - - IF NOT EMPTY(lcTempDBC) - CLOSE DATABASES - ERASE (FORCEEXT(lcTempDBC,'DBC')) - ERASE (FORCEEXT(lcTempDBC,'DCT')) - ERASE (FORCEEXT(lcTempDBC,'DCX')) - ENDIF - - RELEASE I, loField, loIndex, loDBFUtils ; - , lcCreateTable, lcLongDec, lcFieldDef, lcIndex, ldLastUpdate, lcTempDBC, lnDataSessionID, lnSelect + STORE NULL TO loIndex + RELEASE I, loIndex, lcIndex, ldLastUpdate ENDTRY @@ -12177,6 +12395,7 @@ DEFINE CLASS c_conversor_prg_a_dbf AS c_conversor_prg_a_bin CASE NOT llBloqueTable_Completed AND toTable.analyzeCodeBlock( @lcLine, @taCodeLines, @I, tnCodeLines ) llBloqueTable_Completed = .T. + EXIT ENDCASE ENDFOR @@ -16377,9 +16596,9 @@ DEFINE CLASS c_conversor_frx_a_prg AS c_conversor_bin_a_prg C_FB2PRG_CODE = C_FB2PRG_CODE + toFoxBin2Prg.get_PROGRAM_HEADER() *SELECT * FROM _TABLAORIG ; - WHERE ObjType IN (1,25,26) ; - ORDER BY ObjType ASC ; - INTO CURSOR TABLABIN_0 READWRITE + WHERE ObjType IN (1,25,26) ; + ORDER BY ObjType ASC ; + INTO CURSOR TABLABIN_0 READWRITE *-- Arreglo bug agrupación de controles. 29/10/2015 SELECT * FROM _TABLAORIG ; WHERE ObjType IN (1,25,26) ; @@ -16557,9 +16776,12 @@ DEFINE CLASS c_conversor_dbf_a_prg AS c_conversor_bin_a_prg , ln_HexFileType, ll_FileHasCDX, ll_FileHasMemo, ll_FileIsDBC, lc_DBC_Name, lnDataSessionID, lnSelect, laDirInfo(1,5) ; , loTable AS CL_DBF_TABLE OF 'FOXBIN2PRG.PRG' ; , loDBFUtils AS CL_DBF_UTILS OF 'FOXBIN2PRG.PRG' ; - , loLang as CL_LANG OF 'FOXBIN2PRG.PRG' + , loLang as CL_LANG OF 'FOXBIN2PRG.PRG' ; + , loFSO AS Scripting.FileSystemObject ; + , loTextStream AS Scripting.TextStream loLang = _SCREEN.o_FoxBin2Prg_Lang + loFSO = toFoxBin2Prg.o_FSO STORE NULL TO loTable, loDBFUtils STORE 0 TO lnCodError loDBFUtils = CREATEOBJECT('CL_DBF_UTILS') @@ -16595,15 +16817,19 @@ DEFINE CLASS c_conversor_dbf_a_prg AS c_conversor_bin_a_prg *-- Exportación de estructura y datos (para Diff solamente) ERASE (.c_OutputFile + '.TMP' ) - toFoxBin2Prg.n_FileHandle = FCREATE( .c_OutputFile + '.TMP' ) + *toFoxBin2Prg.n_FileHandle = FCREATE( .c_OutputFile + '.TMP' ) + loTextStream = loFSO.CreateTextFile(.c_OutputFile + '.TMP' ) && Replace VFP low-level file funcs.because the 8-16KB limit. + toFoxBin2Prg.o_TextStream = loTextStream IF toFoxBin2Prg.n_FileHandle = -1 THEN ERROR 102, (.c_OutputFile) ENDIF - FWRITE( toFoxBin2Prg.n_FileHandle, C_FB2PRG_CODE ) + *FWRITE( toFoxBin2Prg.n_FileHandle, C_FB2PRG_CODE ) + loTextStream.WriteLine( C_FB2PRG_CODE ) && Replace VFP low-level file funcs.because the 8-16KB limit. loTable.toText( ln_HexFileType, ll_FileHasCDX, ll_FileHasMemo, ll_FileIsDBC, lc_DBC_Name, .c_InputFile, lc_FileTypeDesc, @toFoxBin2Prg ) - FCLOSE( toFoxBin2Prg.n_FileHandle ) + *FCLOSE( toFoxBin2Prg.n_FileHandle ) + loTextStream.Close() DO CASE CASE toFoxBin2Prg.c_SimulateError = 'SIMERR_I1' @@ -16675,7 +16901,10 @@ DEFINE CLASS c_conversor_dbf_a_prg AS c_conversor_bin_a_prg FINALLY USE IN (SELECT("TABLABIN")) - FCLOSE( toFoxBin2Prg.n_FileHandle ) + *FCLOSE( toFoxBin2Prg.n_FileHandle ) + IF VARTYPE(loTextStream) = "O" THEN + loTextStream.Close() + ENDIF *-- Cierro DBC FOR I = 1 TO ADATABASES(laDatabases2) @@ -16686,8 +16915,8 @@ DEFINE CLASS c_conversor_dbf_a_prg AS c_conversor_bin_a_prg ENDIF ENDFOR - STORE NULL TO loTable, loDBFUtils - RELEASE toModulo, toEx, toFoxBin2Prg ; + STORE NULL TO loTable, loDBFUtils, loTextStream, toFoxBin2Prg.o_TextStream + RELEASE toModulo, toEx, toFoxBin2Prg, loTextStream ; , lnCodError, laDatabases, lnDatabases_Count, laDatabases2, lnLen, lc_FileTypeDesc ; , ln_HexFileType, ll_FileHasCDX, ll_FileHasMemo, ll_FileIsDBC, lc_DBC_Name, lnDataSessionID, lnSelect ; , loTable, loDBFUtils @@ -17136,7 +17365,7 @@ DEFINE CLASS CL_CUS_BASE AS CUSTOM *-- Verifico si el carácter es un separador de cadenas: '"[ X = AT( SUBSTR(lcStr, I, 1), lcSeparadoresIzq) - + IF X > 0 THEN lnAT1 = AT(laSeparador(X,1), lcStr) ENDIF @@ -17311,7 +17540,7 @@ DEFINE CLASS CL_COL_BASE AS COLLECTION *-- Verifico si el carácter es un separador de cadenas: '"[ X = AT( SUBSTR(lcStr, I, 1), lcSeparadoresIzq) - + IF X > 0 THEN lnAT1 = AT(laSeparador(X,1), lcStr) ENDIF @@ -22687,14 +22916,18 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE + [] ; + [] ; + [] ; + + [] ; + + [] ; + [] *-- Modulo _Version = 0 _SourceFile = '' + _I = 0 *-- Table Info + _TableName = '' _CodePage = 0 _Database = '' _FileType = '' @@ -22725,14 +22958,17 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE * taCodeLines (!@ IN ) Array de líneas del programa analizado * I (!@ IN/OUT) Número de línea en análisis * tnCodeLines (!@ IN ) Cantidad de líneas del programa analizado + * toFoxBin2Prg (@! IN ) Referencia de toFoxBin2Prg *--------------------------------------------------------------------------------------------------- - LPARAMETERS tcLine, taCodeLines, I, tnCodeLines + LPARAMETERS tcLine, taCodeLines, I, tnCodeLines, toFoxBin2Prg TRY - LOCAL llBloqueEncontrado, lcPropName, lcValue, loEx AS EXCEPTION ; + LOCAL llBloqueEncontrado, lcPropName, lcValue, llFieldsEvaluated, llIndexesEvaluated ; + , loEx AS EXCEPTION ; , loFields AS CL_DBF_FIELDS OF 'FOXBIN2PRG.PRG' ; - , loIndexes AS CL_DBF_INDEXES OF 'FOXBIN2PRG.PRG' - STORE NULL TO loIndexes, loFields + , loIndexes AS CL_DBF_INDEXES OF 'FOXBIN2PRG.PRG' ; + , loRecords AS CL_DBF_RECORDS OF 'FOXBIN2PRG.PRG' + STORE NULL TO loIndexes, loFields, loRecords STORE '' TO lcPropName, lcValue IF LEFT(tcLine, LEN(C_TABLE_I)) == C_TABLE_I @@ -22749,13 +22985,28 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE CASE C_TABLE_F $ tcLine && Fin EXIT - CASE C_FIELDS_I $ tcLine + CASE NOT llFieldsEvaluated AND C_FIELDS_I $ tcLine loFields = ._Fields loFields.analyzeCodeBlock( @tcLine, @taCodeLines, @I, tnCodeLines ) + llFieldsEvaluated = .T. - CASE C_INDEXES_I $ tcLine + CASE NOT llIndexesEvaluated AND C_INDEXES_I $ tcLine loIndexes = ._Indexes loIndexes.analyzeCodeBlock( @tcLine, @taCodeLines, @I, tnCodeLines ) + llIndexesEvaluated = .T. + + CASE C_RECORDS_I $ tcLine + IF llFieldsEvaluated + * Pensado para poder llamar a este método 2 veces: + * > La 1ra.para evaluar Campos e Indices, y poder crear la estructura de la tabla + * al finalizar este paso. + * > La 2da.para cargar los registros, luego de que se haya creado la tabla, + * así se van volcando directamente y no se guardan en memoria. + EXIT + ENDIF + + loRecords = ._Records + loRecords.analyzeCodeBlock( @tcLine, @taCodeLines, @I, tnCodeLines, ._Fields, @toFoxBin2Prg ) OTHERWISE && Otro valor *-- Estructura a reconocer: @@ -22765,6 +23016,8 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE .ADDPROPERTY( '_' + lcPropName, lcValue ) ENDCASE ENDFOR + + ._I = I ENDWITH && THIS ENDIF @@ -22780,8 +23033,8 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE THROW FINALLY - STORE NULL TO loIndexes, loFields - RELEASE lcPropName, lcValue, loFields, loIndexes + STORE NULL TO loIndexes, loFields, loRecords + RELEASE lcPropName, lcValue, loFields, loIndexes, loRecords ENDTRY @@ -22808,15 +23061,20 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE #ENDIF TRY - LOCAL lcText, lcTableCFG, lcIndexKey, lcIndexFile, laConfig(1), lcValue, lcConfigItem ; + LOCAL lcText, lcIndexKey, lcIndexFile, laConfig(1), lcValue, lcConfigItem ; , lc_DBF_Conversion_Order, lc_DBF_Conversion_Condition, llExportData, laDirFile(1,5), lnFileCount ; , loEx AS EXCEPTION ; + , loFSO AS Scripting.FileSystemObject ; + , loTextStream AS Scripting.TextStream ; + , loDBF_CFG AS CL_DBF_CFG OF 'FOXBIN2PRG.PRG' ; , loRecords AS CL_DBF_RECORDS OF 'FOXBIN2PRG.PRG' ; , loFields AS CL_DBF_FIELDS OF 'FOXBIN2PRG.PRG' ; , loIndexes AS CL_DBF_INDEXES OF 'FOXBIN2PRG.PRG' + *** DH 06/02/2014: created variables LOCAL laFields[1], lnFieldCount - + loFSO = toFoxBin2Prg.o_FSO + loTextStream = toFoxBin2Prg.o_TextStream STORE NULL TO loIndexes, loFields, loRecords STORE 0 TO lnFileCount lcText = '' @@ -22843,37 +23101,18 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE lcText = lcText + loIndexes.toText( '', '', tc_InputFile, @toFoxBin2Prg ) *-- If table CFG exists, use it for DBF-specific configuration. FDBOZZO. 2014/06/15 - lcTableCFG = tc_InputFile + '.CFG' - lnFileCount = ADIR(laDirFile, lcTableCFG) + lnFileCount = toFoxBin2Prg.get_DBF_Configuration( FORCEEXT(tc_InputFile, 'DBF'), @loDBF_CFG, .T. ) - IF toFoxBin2Prg.DBF_Conversion_Support = 4 ; && BIN2PRG (DATA EXPORT FOR DIFF) - OR toFoxBin2Prg.DBF_Conversion_Support = 1 AND lnFileCount = 1 THEN - llExportData = .T. - ENDIF + DO CASE + CASE INLIST(toFoxBin2Prg.DBF_Conversion_Support, 4, 8) ; && BIN2TXT (DATA EXPORT FOR DIFF) + OR INLIST(toFoxBin2Prg.DBF_Conversion_Support, 1, 2) AND lnFileCount = 1 + *-- ASUNCIÓN: Si hay un archivo DBF.CFG, es porque se quiere exportar datos, si no, no debe crearse el DBF.CFG + llExportData = .T. + ENDCASE IF llExportData THEN IF lnFileCount = 1 - toFoxBin2Prg.writeLog() - toFoxBin2Prg.writeLog('* Found configuration file: ' + lcTableCFG) - - *-- Leer valores de configuración - FOR I = 1 TO ALINES( laConfig, FILETOSTR( lcTableCFG ), 1+4 ) - lcConfigItem = LOWER( laConfig(I) ) - - DO CASE - CASE INLIST( LEFT( lcConfigItem, 1 ), '*', '#', '/', "'" ) - LOOP - - CASE LEFT( lcConfigItem, 21 ) == LOWER('DBF_Conversion_Order:') - lc_DBF_Conversion_Order = ALLTRIM( SUBSTR( laConfig(I), 22 ) ) - toFoxBin2Prg.writeLog(' ' + JUSTFNAME(lcTableCFG) + ' -> DBF_Conversion_Order: ' + lc_DBF_Conversion_Order ) - - CASE LEFT( lcConfigItem, 25 ) == LOWER('DBF_Conversion_Condition:') - lc_DBF_Conversion_Condition = ALLTRIM( SUBSTR( laConfig(I), 26 ) ) - toFoxBin2Prg.writeLog(' ' + JUSTFNAME(lcTableCFG) + ' -> DBF_Conversion_Condition: ' + lc_DBF_Conversion_Condition ) - - ENDCASE - ENDFOR + lc_DBF_Conversion_Order = loDBF_CFG.DBF_Conversion_Order IF NOT EMPTY(lc_DBF_Conversion_Order) lcIndexFile = FORCEEXT(tc_InputFile,'IDX') @@ -22882,10 +23121,13 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE ENDIF ENDIF + ENDIF - *** DH 06/02/2014: added _Records + *** DH 06/02/2014: added _Records + IF llExportData loRecords = THIS._Records - FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) + *FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) + loTextStream.WriteLine( lcText ) && Replace VFP low-level file funcs.because the 8-16KB limit. loRecords.toText(@laFields, lnFieldCount, lc_DBF_Conversion_Condition, @toFoxBin2Prg) lcText = '' ENDIF @@ -22895,7 +23137,8 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE <<>> ENDTEXT - FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) + *FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) + loTextStream.WriteLine( lcText ) && Replace VFP low-level file funcs.because the 8-16KB limit. lcText = '' @@ -22907,12 +23150,13 @@ DEFINE CLASS CL_DBF_TABLE AS CL_CUS_BASE THROW FINALLY - STORE NULL TO loIndexes, loFields, loRecords - RELEASE loFields, loIndexes, loRecords IF NOT EMPTY(lcIndexFile) AND FILE(lcIndexFile) SET INDEX TO ERASE (lcIndexFile) ENDIF + + STORE NULL TO loIndexes, loFields, loRecords, loDBF_CFG, loTextStream + RELEASE loFields, loIndexes, loRecords, loDBF_CFG, loTextStream ENDTRY RETURN lcText @@ -23031,7 +23275,7 @@ DEFINE CLASS CL_DBF_FIELDS AS CL_COL_BASE *-- of DBF with this field. taFields(I,17) = 1 ENDIF - + lcText = lcText + loField.toText( @taFields, I ) ENDFOR @@ -23503,9 +23747,82 @@ DEFINE CLASS CL_DBF_RECORDS AS CL_COL_BASE * taCodeLines (@! IN ) Array de líneas del programa analizado * I (@! IN/OUT) Número de línea en análisis * tnCodeLines (@! IN ) Cantidad de líneas del programa analizado + * toFields (@! IN ) Estructura de los campos + * toFoxBin2Prg (@! IN ) Referencia de toFoxBin2Prg *--------------------------------------------------------------------------------------------------- - LPARAMETERS tcLine, taCodeLines, I, tnCodeLines - *** DH 06/02/2014: not implemented + LPARAMETERS tcLine, taCodeLines, I, tnCodeLines, toFields, toFoxBin2Prg + + #IF .F. + LOCAL toFields AS CL_DBF_FIELDS OF 'FOXBIN2PRG.PRG' + LOCAL toFoxBin2Prg AS c_foxbin2prg OF 'FOXBIN2PRG.PRG' + #ENDIF + + TRY + LOCAL llBloqueEncontrado, lcPropName, lcValue, lcAlias, loEx AS EXCEPTION ; + , loRecord AS CL_DBF_RECORD OF 'FOXBIN2PRG.PRG' ; + , loRecordData as Object + STORE NULL TO loIndex + STORE '' TO lcPropName, lcValue, lcAlias + + IF LEFT(tcLine, LEN(C_RECORDS_I)) == C_RECORDS_I + llBloqueEncontrado = .T. + + WITH THIS AS CL_DBF_RECORDSS OF 'FOXBIN2PRG.PRG' + lcAlias = ALIAS() + CURSORSETPROP("Buffering", 3) + loRecord = NULL + loRecord = CREATEOBJECT("CL_DBF_RECORD") + + FOR I = I + 1 TO tnCodeLines + .set_Line( @tcLine, @taCodeLines, I ) + + DO CASE + CASE EMPTY( tcLine ) + LOOP + + CASE C_RECORDS_F $ tcLine && Fin + EXIT + + CASE '> <<>> <> ENDTEXT - FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) + *FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) + loTextStream.WriteLine( lcText ) && Replace VFP low-level file funcs.because the 8-16KB limit. lcText = '' loRecord = CREATEOBJECT('CL_DBF_RECORD') @@ -23548,16 +23869,16 @@ DEFINE CLASS CL_DBF_RECORDS AS CL_COL_BASE SCAN FOR &tc_DBF_Conversion_Condition. I = I + 1 lcText = loRecord.toText(@taFields, tnField_Count) - FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) - IF MOD(I,1000) = 0 THEN - toFoxBin2Prg.updateProgressbar( 'Exporting DBF Data...', 1+(I/lnReccount), 3, 2 ) - - IF MOD(I,10000) = 0 THEN - FFLUSH( toFoxBin2Prg.n_FileHandle, .T. ) - ENDIF + *FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) + loTextStream.WriteLine( lcText ) && Replace VFP low-level file funcs.because the 8-16KB limit. + IF MOD(I,100) = 0 OR LEN(lcText) > 8*1024 THEN + toFoxBin2Prg.updateProgressbar( 'Exporting DBF Data... ' + TRANSFORM(I) + '/' + TRANSFORM(lnReccount) + '', 1+(I/lnReccount), 3, 2 ) + DOEVENTS + *FFLUSH( toFoxBin2Prg.n_FileHandle, .T. ) ENDIF ENDSCAN + toFoxBin2Prg.updateProgressbar( 'Data exported! ', 1+(lnReccount/lnReccount), 3, 2 ) lcText = '' TEXT TO lcText ADDITIVE TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 @@ -23565,7 +23886,8 @@ DEFINE CLASS CL_DBF_RECORDS AS CL_COL_BASE <<>> ENDTEXT - FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) + *FWRITE( toFoxBin2Prg.n_FileHandle, lcText ) + loTextStream.WriteLine( lcText ) && Replace VFP low-level file funcs.because the 8-16KB limit. lcText = '' @@ -23578,8 +23900,8 @@ DEFINE CLASS CL_DBF_RECORDS AS CL_COL_BASE THROW FINALLY - STORE NULL TO loRecord - RELEASE loRecord + STORE NULL TO loRecord, loTextStream + RELEASE loRecord, loTextStream ENDTRY @@ -23596,6 +23918,8 @@ DEFINE CLASS CL_DBF_RECORD AS CL_CUS_BASE LOCAL THIS AS CL_DBF_RECORD OF 'FOXBIN2PRG.PRG' #ENDIF + _MEMBERDATA = [] ; + + [] PROCEDURE analyzeCodeBlock @@ -23605,9 +23929,143 @@ DEFINE CLASS CL_DBF_RECORD AS CL_CUS_BASE * taCodeLines (@! IN ) Array de líneas del programa analizado * I (@! IN/OUT) Número de línea en análisis * tnCodeLines (@! IN ) Cantidad de líneas del programa analizado + * toFields (@! IN ) Estructura de los campos *--------------------------------------------------------------------------------------------------- - LPARAMETERS tcLine, taCodeLines, I, tnCodeLines - *** DH 06/02/2014: not implemented + LPARAMETERS tcLine, taCodeLines, I, tnCodeLines, toFields + + #IF .F. + LOCAL toFields AS CL_DBF_FIELDS OF 'FOXBIN2PRG.PRG' + #ENDIF + + TRY + LOCAL llBloqueEncontrado, lcFieldName, lcValue, luValue, loEx AS EXCEPTION ; + , loField as CL_DBF_FIELD OF 'FOXBIN2PRG.PRG' + STORE '' TO lcFieldName, lcValue + + IF 'VALOR + lcFieldName = STREXTRACT( tcLine, '<', '>', 1, 0 ) + lcValue = STREXTRACT( tcLine, '<' + lcFieldName + '>', '', 1, 0+2 ) + loField = toFields.Item(lcFieldName) + + lcFieldType = loField._Type + llNoCPTran = CAST( loField._NoCPTran as Logical) + + DO CASE + CASE lcFieldType == 'L' && Logical (Boolean) + luValue = CAST(lcValue as Logical) + + CASE lcFieldType == 'G' && General (NOT SUPPORTED) + luValue = '' + + CASE lcFieldType == 'W' && Blob (Memo binario) + luValue = STRCONV(lcValue,14) + + CASE lcFieldType == 'Q' && Varbinary + luValue = STRCONV(lcValue,14) + + CASE lcFieldType == 'V' && Varchar + IF llNoCPTran + *-- If NoCPTran, then must encode in b64binary + luValue = STRCONV(lcValue,14) + ELSE + luValue = .Decode(lcValue) + ENDIF + + CASE lcFieldType == 'M' && Memo + IF llNoCPTran + *-- If NoCPTran, then must encode in b64binary + luValue = STRCONV(lcValue,14) + ELSE + * Si el memo es multi-línea, leer hasta encontrar el final ']]>' del CDATA. + luValue = '' + DO WHILE NOT EMPTY(lcValue) + IF ']]>' $ tcLine THEN + luValue = .Decode(lcValue, .T.) + EXIT + ELSE + I = I + 1 + .set_Line( @tcLine, @taCodeLines, I ) + lcValue = lcValue + CR_LF + tcLine + ENDIF + ENDDO + ENDIF + + CASE lcFieldType == 'D' && Date + luValue = CAST(lcValue as Date) + + CASE lcFieldType == 'T' && Datetime + luValue = CAST(lcValue as DateTime) + + CASE lcFieldType == 'Y' && Currency + luValue = CAST(lcValue as Currency) + + CASE lcFieldType == 'I' && Integer + luValue = CAST(lcValue as Integer) + + CASE lcFieldType == 'B' && Double + luValue = CAST(lcValue as Double) + + CASE lcFieldType == 'F' && Float + luValue = CAST(lcValue as Float) + + CASE lcFieldType == 'N' && Numeric + luValue = CAST(lcValue as Numeric) + + OTHERWISE && Asume 'C' && Character + IF llNoCPTran + *-- If NoCPTran, then must encode in b64binary + luValue = STRCONV(lcValue,14) + ELSE + luValue = .Decode(RTRIM(lcValue)) + ENDIF + + ENDCASE + + IF lcFieldType == 'G' + *-- Saltar campos General + ELSE + REPLACE (lcFieldName) WITH (luValue) + ENDIF + + ENDCASE + ENDFOR + ENDWITH && THIS + ENDIF + + CATCH TO loEx + IF loEx.ERRORNO = 1470 && Incorrect property name. + loEx.USERVALUE = 'I=' + TRANSFORM(I) + ', tcLine=' + TRANSFORM(tcLine) + ', lcFieldName=[' + TRANSFORM(lcFieldName) + '], Value=[' + TRANSFORM(lcValue) + ']' + ENDIF + + IF THIS.n_Debug > 0 AND _VFP.STARTMODE = 0 + SET STEP ON + ENDIF + + THROW + + FINALLY + STORE NULL TO loField + RELEASE loField + + ENDTRY + + RETURN llBloqueEncontrado ENDPROC @@ -23622,41 +24080,66 @@ DEFINE CLASS CL_DBF_RECORD AS CL_CUS_BASE EXTERNAL ARRAY taFields TRY - LOCAL I, lcText, loEx AS EXCEPTION, lcField, luValue, lcFieldType + LOCAL I, lcText, loEx AS EXCEPTION, lcField, luValue, lcFieldType, llNoCPTran lcText = '' WITH THIS AS CL_DBF_RECORD OF 'FOXBIN2PRG.PRG' *** FDBOZZO 2014/07/15: New "num" property invalidates the use of REGNUM field TEXT TO lcText TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 - <<>> <> + <<>> <> ENDTEXT FOR I = 1 TO tnField_Count lcField = taFields[I, 1] lcFieldType = taFields[I, 2] + llNoCPTran = taFields[I, 6] - *** FDBOZZO 2014/07/15: Added field restrictions on binary and general fields - DO CASE - CASE lcFieldType == 'G' - luValue = 'GENERAL FIELD NOT SUPPORTED' - *CASE lcFieldType == 'W' - * luValue = 'BLOB FIELD NOT SUPPORTED' - *CASE lcFieldType == 'Q' - * luValue = 'VARBINARY FIELD NOT SUPPORTED' - OTHERWISE + IF lcFieldType == 'G' + *-- Saltar campos de tipo General + ELSE luValue = EVALUATE(lcField) - ENDCASE - DO CASE - CASE taFields[I, 2] $ 'CMV' - luValue = TRIM(luValue) - IF .Encode(luValue) <> luValue - luValue = '' - ENDIF &&.Encode(luValue) <> luValue - ENDCASE - TEXT TO lcText TEXTMERGE NOSHOW flags 1+2 PRETEXT 1+2 additive - <<>> <<'<' + lcField + '>'>><><<''>> - ENDTEXT + DO CASE + CASE lcFieldType $ 'GWQVCM' AND luValue == '' ; && Vacío + OR lcFieldType $ 'DT' AND luValue == {} ; + OR lcFieldType $ 'YIBFN' AND luValue == 0 + + CASE lcFieldType == 'W' && Blob (Memo binario) + luValue = STRCONV(luValue,13) + + CASE lcFieldType == 'Q' && Varbinary + luValue = STRCONV(luValue,13) + + CASE lcFieldType == 'V' && Varchar + IF llNoCPTran THEN + *-- If NoCPTran, then must encode in b64binary + luValue = STRCONV(luValue,13) + ELSE + luValue = .Encode(luValue) + ENDIF + + CASE lcFieldType $ 'C' && Character + IF llNoCPTran THEN + *-- If NoCPTran, then must encode in b64binary + luValue = STRCONV(luValue,13) + ELSE + luValue = .Encode(RTRIM(luValue)) + ENDIF + + CASE lcFieldType $ 'M' && Memo + IF llNoCPTran THEN + *-- If NoCPTran, then must encode in b64binary + luValue = STRCONV(luValue,13) + ELSE + luValue = .Encode(RTRIM(luValue), .T.) + ENDIF + + ENDCASE + + TEXT TO lcText TEXTMERGE NOSHOW flags 1+2 PRETEXT 1+2 additive + <<>> <<'<' + lcField + '>'>><><<''>> + ENDTEXT + ENDIF NEXT TEXT TO lcText TEXTMERGE NOSHOW FLAGS 1+2 PRETEXT 1+2 additive @@ -23677,17 +24160,41 @@ DEFINE CLASS CL_DBF_RECORD AS CL_CUS_BASE ENDPROC PROCEDURE Encode - LPARAMETERS tcString + LPARAMETERS tcString, tl_isCDATA LOCAL lcString - lcString = STRTRAN(tcString, '&', '&') - lcString = STRTRAN(lcString, '>', '>') - lcString = STRTRAN(lcString, '<', '<') - lcString = STRTRAN(lcString, '"', '"') - lcString = STRTRAN(lcString, "'", ''') - lcString = STRTRAN(lcString, '/', '/') - lcString = STRTRAN(lcString, CHR(13), ' ') - lcString = STRTRAN(lcString, CHR(10), ' ') - lcString = STRTRAN(lcString, CHR(9), ' ') + IF tl_isCDATA THEN + *lcString = '', ']]]]>') + ']]>' + lcString = '', ']]>') + ']]>' + ELSE + lcString = STRTRAN(tcString, '&', '&') + lcString = STRTRAN(lcString, '>', '>') + lcString = STRTRAN(lcString, '<', '<') + lcString = STRTRAN(lcString, '"', '"') + lcString = STRTRAN(lcString, "'", ''') + lcString = STRTRAN(lcString, '/', '/') + lcString = STRTRAN(lcString, CHR(13), ' ') + lcString = STRTRAN(lcString, CHR(10), ' ') + lcString = STRTRAN(lcString, CHR(9), ' ') + ENDIF + RETURN lcString + ENDPROC + + PROCEDURE Decode + LPARAMETERS tcString, tl_isCDATA + LOCAL lcString + IF tl_isCDATA THEN + lcString = STRTRAN( STRTRAN( STREXTRACT( tcString, ''), '<![CDATA[', '') + ELSE + lcString = STRTRAN(tcString, ' ', CHR(9)) + lcString = STRTRAN(lcString, ' ', CHR(10)) + lcString = STRTRAN(lcString, ' ', CHR(13)) + lcString = STRTRAN(lcString, '/', '/') + lcString = STRTRAN(lcString, ''', "'") + lcString = STRTRAN(lcString, '"', '"') + lcString = STRTRAN(lcString, '<', '<') + lcString = STRTRAN(lcString, '>', '>') + lcString = STRTRAN(lcString, '&', '&') + ENDIF RETURN lcString ENDPROC @@ -27474,3 +27981,23 @@ DEFINE CLASS CL_LANG AS Custom ENDPROC ENDDEFINE + + + +DEFINE CLASS CL_DBF_CFG AS CUSTOM + _MEMBERDATA = [] ; + + [] ; + + [] ; + + [] ; + + [] + + #IF .F. + LOCAL THIS AS CL_DBF_CFG OF 'FOXBIN2PRG.PRG' + #ENDIF + + + *-- Configuration class. By default asumes master value, except when overriding one. + DBF_Conversion_Order = '' + DBF_Conversion_Condition = '' + DBF_Conversion_Support = 0 +ENDDEFINE