Importar presupuestos de Excel sin macros (de XLS a BC3)
Una fase del trabajo de oficina, tanto en redacción de proyectos como durante la construcción, consiste en medir y traspasar, a un documento de presupuesto, dichas mediciones. Afortunadamente se dispone de un formato de intercambio relativamente simple FIECBD/BC3 entre ellos y los programas del ramo disponen de exportación a Excel desde su formato nativo. Sin embargo este camino es unidireccional, -> de FormatoPropietario/BC3 a XLS, y el camino inverso no está cerrado, porque es específico de cada solución de exportación.
Suponiendo que se ha adoptado la muy conocida y eficiente BC3ToExcel.com, es posible convertir de BC3 a XLS, sobre el que realizar las oportunas modificaciones en una aplicación infinitamente más versátil que las aplicaciones comerciales dedicadas, porque además de poder trabajar con fórmulas, se abre a referencias de tipo “base de datos”, rangos,….
Es posible realizar la exportación desde un Libro de este tipo a formato BC3 con apenas 10 fórmulas y, no es necesario tan siquiera recurrir a macros, aunque una pequeña rutina libera del trabajo manual final necesario para tenerlo todo en orden.
Las fórmulas son las siguientes:
- Para la hoja “CuadrodePrecios”, se ocupan dos columnas, donde se requieren las fórmulas:
Concepto Texto =SI($D#=””;””;”~C”&”|”&$D#&”|”&$E#&”|”&$F#&”|”&SUSTITUIR(TEXTO($G#;”0,00″);”,”;”.”)&”|”&TEXTO(HOY();”ddmmaa”)&”|”&$C#&”|”) =SI($D#=””;””;”~T”&”|”&$D#&”|”&$I#&”|”) Para la hoja “Precios Descompuestos”, se emplea una columna, con la fórmula: =SI($B#<>””;”|”&CARACTER(13)&CARACTER(10)&”~D”&”|”&$B#&”|”;SI($C#<>””;$C#&”\”&”1″&”\”&SUSTITUIR(TEXTO($F#;”0,0000″);”,”;”.”)&”\”;””))
- Para la hoja “Presupuesto”, se ocupa el rango de columnas “Q” a “AA”, para 0 (Raiz) y 1 nivel de desglose (aunque es posible incrementarlo hasta el nivel deseado agregando más columnas por pares y editando el código de la fórmula):
Nivel Posición Código capitulos Descompuestos Check Nivel0 Nivel1 Mediciones =SI(ESBLANCO($C#);””;SUMA(LARGO($C#))-LARGO(SUSTITUIR($C#;”.”;””))+1) =SI(ESBLANCO($C#);””;SUSTITUIR($C#;”.”;”\”)) =SI($B#=”#”;$D#&”#”;DESREF($T#;-1;0)) =SI(B#=”#”;”~C|”&$T#&”||”&$F#&”|”&SUSTITUIR(TEXTO($O#;”0,00″);”,”;”.”)&”|”&TEXTO(HOY();”ddmmaa”)&”|”&”0″&”|”;””) =SI($B#=”#”;”|”&CARACTER(13)&CARACTER(10)&”~D|”&$T#&”|”;””) =O($B#=”B”;$B#=”C”;$B#=”D”) =SI(O($B#=”#”;$W#);$D#;””) =”~C|”&”RAIZ##”&”||”&”PROYECTO”&”|”&SUSTITUIR(TEXTO($O#;”0,00″);”,”;”.”)&”|”&TEXTO(HOY();”ddmmaa”)&”|”&”0″&”|”&”~D|”&”RAIZ##”&”|” =SI($R#=1;SI($B#=”#”;$X#&”\1\1\”;””);””) =SI($R#=1;$U#;””) =SI($R#=1;SI($B#=”#”;$V#;””);SI($R#=2;$X#&”\1\1\”;””)) =SI($W#;”|”&CARACTER(13)&CARACTER(10)&”~M|”&$T#&”\”&$D#&”|”&$S#&”|”&SUSTITUIR(TEXTO($L#;”0,00″);”,”;”.”)&”|”;
SI(Y(ESBLANCO($D#);ESBLANCO($B#);Y(NO(DESREF($B#;-1;0)=”S”));NO(DESREF($B#;-1;0)=”M”));
SI(O($K#=””;$K#<>0); “\”&SI(ESBLANCO($F#);””;SUSTITUIR(TEXTO($F#;”0,00″);”,”;”.”))&
“\”&SI(ESBLANCO($G#);””;SUSTITUIR(TEXTO($G#;”0,00″);”,”;”.”))&
“\”&SI(ESBLANCO($H#);””;SUSTITUIR(TEXTO($H#;”0,00″);”,”;”.”))&
“\”&SI(ESBLANCO($I#);””;SUSTITUIR(TEXTO($I#;”0,00″);”,”;”.”))&
“\”&SI(ESBLANCO($J#);””;SUSTITUIR(TEXTO($J#;”0,00″);”,”;”.”))&”\”;””);””))
En estas fórmulas el carácter “#” sustituye al número de fila en que se inserta la fórmula.
No queda más que arrastrar las fórmulas al rango usado, y copiar, por columnas a un archivo de texto. Para las columnas de código “~D” y “~M” se hace preciso una pequeña operación manual, consistente en eliminar el primer carácter “|” y añadirlo a la cola del texto de esa columna. En todo caso, el texto de la columna siempre debe terminar con el carácter “|”.Finalmente será preciso añadir los parámetros de operación del archivo BC3, que son las dos líneas siguientes:
~V|-|FIEBDC-3/2002|-||ANSI|
~K|\3\3\4\2\2\2\2\EUR\|0|
Con esto será posible disponer de un archivo de vuelta en formato BC3, listo para importar y generar los listados.Acompaño, a continuación, el código de la rutina que permite, para mi configuración, realizar el trabajo manual. Será preciso modificar los nombres de hojas en su caso, y seleccionar las columnas a exportar, en cada hoja, sólo las marcadas en azul.
Sub XLSToBC3()
' Exporta a BC3 desde XLS
Dim oWsh As Excel.Worksheet
Dim hndOut As Integer
Dim FilePath_BC3 As Variant
' Get filename (save file dialog)
FilePath_BC3 = Application.GetSaveAsFilename(FileFilter:="FIEBDC-3/20## (*.bc3), *.bc3, " & _
"All files" & "(*.*), *.*", _
Title:="Save as BC3", _
InitialFileName:=VBA.Environ$("UserProfile") & "\Documents\")
If FilePath_BC3 = False Then Exit Sub ' make sure the user hasn't canceled the dialog
hndOut = VBA.FreeFile
Open VBA.CStr(FilePath_BC3) For Output Shared As #hndOut
Print #hndOut, "~V|-|FIEBDC-3/2002|-||ANSI|"
Print #hndOut, "~K|\3\3\4\2\2\2\2\EUR\|0|"
Set oWsh = Worksheets("Cuadro de Precios"): oWsh.Activate
Call ExportarHoja(oWsh, hndOut)
Set oWsh = Worksheets("Precios Descompuestos"): oWsh.Activate
Call ExportarHoja(oWsh, hndOut)
Set oWsh = Worksheets("Presupuesto"): oWsh.Activate
Call ExportarHoja(oWsh, hndOut)
Close #hndOut
End Sub
Private Sub ExportarHoja(ByVal oWsh As Excel.Worksheet, _
ByVal hndOut As Integer)
Dim oSelection As Excel.Range
Dim oColumn As Excel.Range
Dim oCell As Excel.Range
Dim strColumn As String
'With oWsh
'Set oSelection = Selection
'If oSelection.Columns.Count = 1 Then
'Do While Application.Intersect(oSelection, Columns("?:??")) Is Nothing
Set oSelection = Application.InputBox("Seleccionar rango de columnas a exportar", , oSelection, , , , , Type:=8)
'Set oSelection = Application.Intersect(oSelection, .Columns("?:??"))
'DoEvents
'If Application.Intersect(oSelection, .Columns("?:??")) Is Nothing Then 'Exit Do
'Loop
'End With
For Each oColumn In oSelection.Columns
strColumn = vbNullString
For Each oCell In oColumn.Cells
If oCell.Value2 <> vbNullString Then
strColumn = strColumn & oCell.Value2 & vbCrLf
End If
Next oCell
strColumn = VBA.Trim$(strColumn)
If VBA.Mid(strColumn, 1, 1) = "|" Then strColumn = VBA.Mid(strColumn, 2) & VBA.Mid(strColumn, 1, 1)
If VBA.Right(strColumn, 1) <> "|" Then strColumn = strColumn & "|"
'MsgBox strColumn
If strColumn <> vbNullString Then Print #hndOut, strColumn & vbNewLine
Next oColumn
oSelection.Select
Set oSelection = Nothing
End Sub