Excel to BC3

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:
    ConceptoTexto
    =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):
  • NivelPosiciónCódigocapitulosDescompuestosCheck 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

Leave a Reply

Your email address will not be published. Required fields are marked *