Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

Enregistrer la Feuil active au Format DBF4

  • Initiateur de la discussion Initiateur de la discussion Atiom
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Atiom

XLDnaute Occasionnel
Bonjour le forum

Je souhaiterais trouver une macro à appliquer sur un bouton que puisse enregistrer le fichier Excel mais au même temps enregistrer la Feuil active de ce même fichier au Format DBF 4.

J’ai effectué une recherche sur le forum mais à mon grand étonnement le sujet DBF n’as pas beaucoup été traité.

Je mets en fichier joint un dossier pour une meilleure compréhension du sujet.

Merci de votre aide
 

Pièces jointes

Re : Enregistrer la Feuil active au Format DBF4

Bonsoir Atiom

Peut-être ce code :

Code:
Sub enreg_dbase()
ActiveWorkbook.Save
lepath = ActiveWorkbook.Path & "\"
    ActiveSheet.Copy
    Application.DisplayAlerts = False
    ActiveWorkbook.SaveAs Filename:=lepath & ActiveSheet.Name & ".dbf", FileFormat:=xlDBF4
    ActiveWindow.Close False
    Application.DisplayAlerts = True
End Sub
 
Re : Enregistrer la Feuil active au Format DBF4

Bonsoir, bhbh et forum

Merci.
Ça fonctionne parfaitement.
Mais j’ai oublié de préciser une petite chose.
Le fichier DBF doit avoir le même nom que le fichier Excel.

Dans ta macro le fichier DBF prend le nom de la Feuil active.
J’ai essayé de remplacer la ligne:

Code:
 ActiveWorkbook.SaveAs Filename:=lepath & ActiveSheet.Name & ".dbf", FileFormat:=xlDBF4

par
 ActiveWorkbook.SaveAs Filename:=lepath & ActiveWorkbook.Name & ".dbf", FileFormat:=xlDBF4

Mais la le fichier DBF prend le nom de Classeur1, et pour moi il est impérative que le Fichier DBF prenne le même nom que le fichier Excel.

Comment je peu modifier la Macro ?

Merci d’avance
 
Re : Enregistrer la Feuil active au Format DBF4

Re-,
essaie :

Code:
ActiveWorkbook.SaveAs Filename:=lepath & Left(ThisWorkbook.Name, Len(ThisWorkbook.Name) - 4) & ".dbf", FileFormat:=xlDBF4

Bonne soirée
 
Re : Enregistrer la Feuil active au Format DBF4

Bonjour le forum,

6 ans après je relance la discussion.
Le code trouvé par bhbh fonctionné parfaitement sur la version 2003.
Je crois que depuis la version 2007, Excel ne permet plus l’enregistrement de fichiers au format .dbf

Du coup j’ai un petit souci puisque au boulot ils viennent d’actualiser tous les PC avec la version 2010.

Je vous remets le code ci-dessous et si quelqu’un à une petite idée de comment je peux contourner le problème, ça serais vraiment sympa.
Merci d’avance

Code:
Private Sub CommandButton1_Click()
ActiveWorkbook.Save
lepath = ActiveWorkbook.Path & "\"
    ActiveSheet.Copy
    Application.DisplayAlerts = False
    ActiveWorkbook.SaveAs Filename:=lepath & Left(ThisWorkbook.Name, Len(ThisWorkbook.Name) - 4) & ".dbf", FileFormat:=xlDBF4
    ActiveWindow.Close False
    Application.DisplayAlerts = True
End Sub
Cordialement
 
Re : Enregistrer la Feuil active au Format DBF4

Bonjour

Tu as donné toi même la réponse à ta question : ce n'est plus possible avec excel 2007 et +... 🙁
save as n'admet plus le fileformat xlDBF4. Donc à part garder un PC sous 2003 pour faire ça, je ne vois pas.
 
Re : Enregistrer la Feuil active au Format DBF4

Bonjour,

Merci Misange et Staple1600 pur vos réponses.
Staple1600 j'ai testé et sur 2007 c'est ok.
Par contre sur 2010 lorsque on enregistre au format .dbf il y a une perte de données.
Il me semble bizarre, est-ce que quelqu’un d’autre pourrait faire un teste ? Et se vraiment c’est le cas ! Ets-ce qu’on peut adapté le code ?
Ci-dessous le code
Merci de votre aide
VB:
Function savedbf() As Boolean
    Dim filename As Variant
    Dim temp As Variant
    Dim currentFile As String
    Dim defaultFile As String
    
    currentFile = ActiveWorkbook.Name
    temp = Split(currentFile, ".")
    temp(UBound(temp)) = "dbf"
    defaultFile = Join(temp, ".")
    If defaultFile = "dbf" Then
        defaultFile = ActiveWorkbook.Name & ".dbf"
    End If
    filename = Application.GetSaveAsFilename(InitialFileName:=defaultFile, FileFilter:="DBF 4 (dBASE IV) (*.dbf),*.dbf", Title:="Save As DBF")
    
    If filename = False Then Exit Function
    
    savedbf = DoSaveDefault(filename)
End Function

Function DoSaveDefault(ByVal filename As String)
    ' Declare DB vars
    Dim path As Variant
    Dim file As Variant
    Dim tfile As Variant
    Dim table As Variant
    Dim dbConn As ADODB.Connection
    
    ' Initialize DB vars
    path = Split(filename, "\")
    file = path(UBound(path))
    file = Replace(Left(file, Len(file) - 4), ".", "_") & Right(file, 4)
    tfile = "__T_DB__.dbf"
    path(UBound(path)) = ""
    path = Join(path, "\")
    table = Left(tfile, 8)
    filename = path & file
    
    ' Check if file exists
    On Error Resume Next
    GetAttr filename
    If Err.Number = 0 Then
        Dim mbResult As VbMsgBoxResult
        mbResult = MsgBox("The file " & file & " already exists. Do you want to replace the existing file?", _
            VbMsgBoxStyle.vbYesNo + VbMsgBoxStyle.vbExclamation, "File Exists")
        If mbResult = vbNo Then
            DoSaveDefault = False
            Exit Function
        Else
            SetAttr filename, vbNormal
            Kill filename
        End If
    End If
    
    Err.Number = 0
    
    GetAttr filename
    If Err.Number = 0 Then
        MsgBox "Unable to remove existing file " & file & ".", vbExclamation, "Error Removing File"
        DoSaveDefault = False
        Exit Function
    End If
    On Error GoTo 0

    ' Open DB connection
    Set dbConn = New ADODB.Connection
    dbConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & path & ";Extended Properties=""DBASE IV;"";"
    
    ' Declare excel vars
    Dim dataRange As Range
    
    Set dataRange = Selection
    
    If dataRange.Areas.Count > 1 Then
        MsgBox "The command you chose cannot be performed with multiple selections. Select a single range and click the command again.", _
            VbMsgBoxStyle.vbCritical, "Error Saving File"
        DoSaveDefault = False
        Exit Function
    End If
    
    ' Expand selection if single cell (Expands selection using the Excel 2003 save DBF behavior)
    'If dataRange.Cells.Count = 1 Then
    '    If IsEmpty(dataRange.Cells(1).Value) Then
    '        MsgBox "The command could not be completed by using the range specified. Select a single cell within the range and try the command again.", _
    '            VbMsgBoxStyle.vbExclamation, "Error Saving File"
    '        DoSaveDefault = False
    '        Exit Function
    '    Else
    '        Set dataRange = dataRange.CurrentRegion
    '    End If
    'End If
    
    ' Expand selection if single cell (Differs from normal Excel 2003 behavior by not stopping at blank rows and columns)
    If dataRange.Cells.Count = 1 Then
        Dim row1 As Integer
        Dim rowN As Integer
        Dim col1 As Integer
        Dim colN As Integer
        Dim cellFirst As Range
        Dim cellLast As Range
    
        row1 = ActiveSheet.Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlNext).row
        col1 = ActiveSheet.Cells.Find(What:="*", SearchOrder:=xlByColumns, SearchDirection:=xlNext).Column
        rowN = ActiveSheet.Cells.Find(What:="*", After:=[A1], SearchOrder:=xlByRows, SearchDirection:=xlPrevious).row
        colN = ActiveSheet.Cells.Find(What:="*", After:=[A1], SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
    
        Set cellFirst = ActiveSheet.Cells(row1, col1)
        Set cellLast = ActiveSheet.Cells(rowN, colN)
        Set dataRange = ActiveSheet.Range(cellFirst.Address, cellLast.Address)
    End If
    
    ' Declare data vars
    Dim i As Integer
    Dim j As Integer
    Dim numCols As Integer
    Dim numDataCols As Integer
    Dim numRows As Long
    Dim createString As String
    Dim fieldpos(), fieldvals(), fieldtypes(), fieldnames(), fieldactive()
    
    numCols = dataRange.Columns.Count
    numDataCols = 0
    numRows = dataRange.Rows.Count
    ReDim fieldtypes(0 To numCols - 1)
    ReDim fieldnames(0 To numCols - 1)
    ReDim fieldactive(0 To numCols - 1)
    
    ' Fill field names
    i = 0
    For Each c In dataRange.Rows(1).Columns
        ' Mark column active if not blank
        If WorksheetFunction.CountA(c.EntireColumn) > 0 Then
            fieldactive(i) = True
            numDataCols = numDataCols + 1
        
            If VarType(c.Value) = vbString Then
                fieldnames(i) = Left(Replace(c.Value, " ", "_"), 10)
            Else
                fieldnames(i) = "N" & c.Column
            End If
        Else
            fieldactive(i) = False
        End If
        
        i = i + 1
    Next
    
    ' Fill field positions
    ReDim fieldpos(0 To numDataCols - 1)
    ReDim fieldvals(0 To numDataCols - 1)
    For i = 0 To numDataCols - 1
        fieldpos(i) = i
    Next
    
    ' Fill field types
    If dataRange.Rows.Count < 2 Then
        For i = 0 To numCols - 1
            If fieldactive(i) Then
                fieldtypes(i) = vbString
            End If
        Next
    Else
        i = 0
        
        For Each c In dataRange.Rows(2).Columns
            If fieldactive(i) Then
                fieldtypes(i) = VarType(c.Value)
            End If
            
            i = i + 1
        Next
    End If
    
    ' Create table
    Dim cat As ADOX.Catalog
    Dim tbl As ADOX.table
    Dim col As ADOX.Column
    Set cat = New ADOX.Catalog
    cat.ActiveConnection = dbConn
    Set tbl = New ADOX.table
    tbl.Name = table
    For i = 0 To numCols - 1
        ' Only add non-blank columns
        If fieldactive(i) Then
            Set col = New ADOX.Column
            col.Name = fieldnames(i)
            fillColumnType col, fieldtypes(i), dataRange.Columns(i + 1)
            tbl.Columns.Append col
            Set col = Nothing
        End If
    Next
    On Error Resume Next
    cat.Tables.Delete table
    On Error GoTo 0
    cat.Tables.Append tbl
    
    ' Populate table
    Dim rs As ADODB.Recordset
    Dim r As Range
    Dim row As Long
    Set rs = New ADODB.Recordset
    
    rs.Open table, dbConn, adOpenDynamic, adLockPessimistic, adCmdTable
    
    If rs.LockType = LockTypeEnum.adLockReadOnly Then
        MsgBox "The recordset is read-only.", vbExclamation, "Error Inserting Record"
    End If
    
    For row = 2 To numRows
        Set r = dataRange.Rows(row)
        ' Only add non-blank rows
        If WorksheetFunction.CountA(r.EntireRow) > 0 Then
            i = 0
            j = 0
            For Each c In r.Cells
                If fieldactive(i) Then
                    fieldvals(j) = getValByVbType(c.Text, fieldtypes(i))
                    j = j + 1
                End If
                i = i + 1
            Next
            rs.AddNew fieldpos, fieldvals
        End If
    Next
    
    ' Close the recordset and connection
    rs.Close
    dbConn.Close
    
    ' Copy file to final destination (this is necessary because the Jet driver limits
    '   the filename to 8 chars before the extension)
    Dim fs As Scripting.FileSystemObject
    Set fs = New Scripting.FileSystemObject
    fs.CopyFile path & tfile, filename
    Set fs = Nothing
    Kill path & tfile
    
    DoSaveDefault = True
End Function

Function fillColumnType(col As ADOX.Column, ByVal vtype As Integer, colrange As Range) As Boolean
    Select Case vtype
        Case vbInteger, vbLong, vbByte
            col.Type = adInteger
        Case vbSingle, vbDouble, vbDouble
            fillColNumberType col, colrange
        Case vbCurrency
            col.Type = adCurrency
        Case vbDate
            col.Type = adDate
        Case vbBoolean
            col.Type = adBoolean
        Case vbString
            fillColStringType col, colrange
        Case Else
            col.Type = adWChar
            col.Precision = 32
    End Select
    
    getAdoTypeFromVbType = True
End Function

Function getValByVbType(ByVal s As String, ByVal t As Integer)
    Dim result As Variant
    result = Null
    
    On Error Resume Next
    Select Case t
        Case vbInteger, vbLong, vbByte
            result = CInt(s)
        Case vbSingle, vbDouble, vbCurrency, vbDecimal
            If CInt(s) <> CDec(s) Then
                result = CDec(s)
            Else
                result = CInt(s)
            End If
        Case vbDate
            result = CDate(s)
        Case vbBoolean
            result = CInt(s) <> 0
        Case vbString
            result = s
        Case Else
            result = Null
    End Select
    On Error GoTo 0
    
    getValByVbType = result
End Function

Function fillColStringType(col As ADOX.Column, r As Range) As Boolean
    Dim lenshort As Integer
    Dim lenlong As Integer
    Dim l As Integer
    
    lenshort = Len(r.Cells(2).Text)
    lenlong = lenshort
    
    For Each c In r.Cells
        If c.row > 1 Then
            l = Len(c.Text)
            If l < lenshort Then
                lenshort = l
            End If
            
            If l > lenlong Then
                lenlong = l
            End If
        End If
    Next
    
    If lenlong > 254 Then
        col.Type = adLongVarWChar
    ElseIf lenlong > 128 And lenlong < 255 Then
        col.Type = adWChar
        col.Precision = 254
    ElseIf lenshort = lenlong And lenlong < 17 Then
        col.Type = adWChar
        col.Precision = lenlong
    Else
        col.Type = adWChar
        col.Precision = ceilPow2(lenlong)
    End If
    
    fillColStringType = True
End Function

Function fillColNumberType(col As ADOX.Column, r As Range) As Boolean
    Dim hasDecimal As Boolean
    Dim t As Boolean
    
    hasDecimal = False
    
    On Error Resume Next
    For Each c In r.Cells
        If c.row > 1 Then
            t = val(c.Text) <> Int(val(c.Text))
            If Err.Number = 0 And t Then
                hasDecimal = True
                Exit For
            End If
        End If
    Next
    On Error GoTo 0
    
    If hasDecimal Then
        col.Type = adNumeric
        col.Precision = 11
        col.NumericScale = 4
    Else
        col.Type = adInteger
    End If
    
    fillColNumberType = True
End Function

Function ceilPow2(x As Integer)
    Dim i As Integer
    i = 2
    Do While i < x
        i = i * 2
    Loop
    
    ceilPow2 = i
End Function
 
Dernière édition:
Re : Enregistrer la Feuil active au Format DBF4

Bonjour,

J’aimerais bien tester la deuxième solution proposé par Staple1600, mais je crois que mon niveau d’anglais ne le permet pas !
Il y a quelque chose que je fais faux.
J’importe le fichier .bas dans le Visual basic et lorsque je veux enregistre la feuille Excel j’ai le message suivants :

Les fonctionnalités suivantes ne peuvent pas être enregistrées dans des classeurs sans macro :
.projet VB


Ets-ce que quelqu’un peux me donner un coup de main et mettre le code ci-dessous dans un fichier Excel ?
Merci
VB:
'#####################################################################################################################
'
'   Description: This tool is a simple macro which can be added to Excel to save the active sheet as DBF file.
'
'   Author: Arnejan van Loenen
'   Version: 1.00
'   Date: March 1, 2011
'
'####################################################################################################################


Sub SaveAsDBF()
On Error GoTo EH
Dim lSaveAsNew As VbMsgBoxResult
lSaveAsNew = MsgBox("Overwrite current document (Yes) or save as new DBF (No)?", vbYesNoCancel)

    Dim lWorkbookPath As String
    Dim lWorkbookName As String

    If lSaveAsNew = vbYes Then
        'overwrite current document
        lWorkbookPath = ActiveWorkbook.Path
        
    ElseIf lSaveAsNew = vbNo Then
        'save as new document
        lWorkbookPath = BrowseFolder("Select Path", msoFileDialogViewDetails)

    Else
        'cancel
        Exit Sub
    End If

lWorkbookName = ActiveWorkbook.ActiveSheet.Name
Call WriteDBF(ActiveWorkbook.ActiveSheet, "12345678", lWorkbookPath)

If lSaveAsNew = vbYes Then
    'close document because otherwise overwrite is not possible
    ActiveWorkbook.Close (False)
    Kill SetFolder(lWorkbookPath) & lWorkbookName & ".dbf"
End If

Name SetFolder(lWorkbookPath) & "12345678.dbf" As SetFolder(lWorkbookPath) & lWorkbookName & ".dbf"
MsgBox "Workbook saved as " & SetFolder(lWorkbookPath) & lWorkbookName & ".dbf"

Exit Sub
EH:
MsgBox "An error occurred: " & vbNewLine & Err.Description
End Sub

Function BrowseFolder(Title As String, _
    Optional InitialView As Office.MsoFileDialogView = _
        msoFileDialogViewList) As String
    Dim V As Variant
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = Title
        .InitialView = InitialView
        .Show
        On Error Resume Next
        Err.Clear
        V = .SelectedItems(1)
        If Err.Number <> 0 Then
            V = vbNullString
        End If
    End With
    BrowseFolder = CStr(V)
End Function

Function SetFolder(pPath As String) As String
    If Not Right(pPath, 1) = "\" Then pPath = pPath & "\"
    SetFolder = pPath
End Function

Sub WriteDBF(pWorksheet As Worksheet, pTableName As String, pPath As String)

On Error GoTo EH
    
    Dim inputFile, Path, fileName, tableName, createTable
    pPath = SetFolder(pPath)
    Dim dBConn
    Set dBConn = OpenDBFConn(pPath)
    
    Dim myExcel, myWorkbook, mySheet, nColumns, column
    Dim fields, row, scan, lThisTableName, sheetCount
    Dim lCreateString
    Dim i As Integer

    nColumns = GetColCount(pWorksheet)
  
    lThisTableName = pTableName
    lCreateString = "CREATE TABLE "
    lCreateString = lCreateString & lThisTableName & " ("
    'create columns
    For i = 1 To nColumns
        lCreateString = lCreateString & "[" & Replace(pWorksheet.Cells(1, i).Value, " ", "_") & "] VARCHAR(" & GetColumnSize(pWorksheet, i) & ") "
        If Not i = nColumns Then lCreateString = lCreateString & ", "
    Next
    lCreateString = lCreateString & " )"
    
    On Error Resume Next
    dBConn.Execute "Drop Table " & lThisTableName
    On Error GoTo 0
    dBConn.Execute lCreateString

    ' Now we have the table, let us write to it
    Dim fieldPos, fieldVals
    ReDim fieldPos(nColumns - 1)
    ReDim fieldVals(nColumns - 1)
    For i = 0 To nColumns - 1
       fieldPos(i) = i
    Next
    
    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset
    Const adOpenDynamic = 2
    Const adLockPessimistic = 2
    Const adCmdTable = 2

    rs.Open pTableName, dBConn, adOpenDynamic, adLockPessimistic, adCmdTable
    row = 2
    Do Until Trim(pWorksheet.Cells(row, 1).Value) = ""
        For i = 1 To nColumns
               fieldVals(i - 1) = pWorksheet.Cells(row, i).Value
        Next
        rs.AddNew fieldPos, fieldVals
        row = row + 1
    Loop

    rs.Close
        
Exit Sub
EH:
    MsgBox "Er is een fout opgetreden. Foutcode: " & Err.Description

End Sub

Function GetColumnSize(pWorksheet As Worksheet, pColumn As Integer) As Integer
    Dim i As Integer
    Dim lMax As Long
    For i = 2 To ActiveWorkbook.ActiveSheet.Cells(1, 1).CurrentRegion.Rows.Count
        If Len(ActiveWorkbook.ActiveSheet.Cells(i, pColumn).Value) > lMax Then lMax = Len(ActiveWorkbook.ActiveSheet.Cells(i, pColumn).Value)
    Next i
    
    Select Case lMax
        Case Is < 10
            GetColumnSize = 10
        Case Is <= 64
            GetColumnSize = 64
        Case Is > 64
            GetColumnSize = 254
    End Select
    
    
End Function

Function GetColCount(pWorksheet As Worksheet) As Integer

    Dim i As Integer
    i = 1
    Do Until Trim(pWorksheet.Cells(1, i).Value) = ""
        i = i + 1
    Loop
    GetColCount = i - 1
End Function

Function OpenDBFConn(Path)
  Dim Conn
  Set Conn = CreateObject("ADODB.Connection")
  Conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
                   "Data Source=" & Path & ";" & _
                   "Extended Properties=""DBASE III;"";"
  Set OpenDBFConn = Conn
End Function
 
Dernière édition:
Re : Enregistrer la Feuil active au Format DBF4

Bonjour à tous

Atiom
Enregistres ton fichier Excel avec l'extension *.xlsm ou *.xls mais pas en *.xlsx

Tu peux aussi copier/coller directement le code que tu viens de poster dans un module (sans passer par l'import)

Pour comprendre l'anglais, cliques-ici 😉
 
Dernière édition:
Re : Enregistrer la Feuil active au Format DBF4

Bonsoir,

Après pas mal de problèmes j’ai fini pour obtenir un fichier qu’enregistre au format .dbf

Certes pas très académique mais il fait exactement ce que j’avais besoin… donc je suis content…

Grand merci au forum et en particulier à Staple1600 pour tous les renseignements fournis.

Merci infiniment.
Je vos mets le fichier… il peut peut-être servir à quelqu’un d’autre…
Regarde la pièce jointe dbf_atiom.zip
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
16
Affichages
1 K
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…