Access

Función VBA para determinar si un archivo es un archivo JSON válido

Después de publicar mi artículo para determinar si un archivo era un archivo XML válido:

Pensé que haría de manera similar por los archivos JSON, ya que también se han vuelto bastante comunes.

Ahora, como todo lo demás en VBA, hay una multitud de enfoques posibles para esto.

Al igual que los archivos XML, los archivos JSON no poseen una firma de archivo también denominada ‘número mágico’. Sin embargo, el problema más grande con los archivos JSON es que, a diferencia de su contraparte XML, no incluyen ninguna línea de declaración para validar fácilmente.

ScriptControl

Mi solución preferida es simplemente usar ScriptControl. Verá, JS nos proporciona la capacidad de validar los archivos JSON con bastante facilidad. En JS moderno usaríamos json.parse (), pero lamentablemente el scriptcontrol es viejo y no nos ofrece eso, pero todavía tenemos eval () que funcionará por igual para nuestras necesidades. Por lo tanto, podemos hacer algo como:

'---------------------------------------------------------------------------------------
' Procedure : JSON_ISValidFile
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : 
' Purpose   : Validates a file to determine if it is a valid JSON file
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - 
' Req'd Refs: Late Binding  -> None required
'             Early Binding -> Microsoft Script Control 1.0
' Dependencies: ReadFileAsText()
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFile     : Fully qualified path and filename to validate
'
' Output Variables:
' ~~~~~~~~~~~~~~~~~
' Boolean:  True    -> Is a JSON file
'           False   -> Is NOT a JSON file
'
' Usage:
' ~~~~~~
' JSON_ISValidFile("C:\Users\Daniel\Downloads\note.json")
'   Returns -> True/False
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2025-04-21
'---------------------------------------------------------------------------------------
Function JSON_ISValidFile(ByVal sFile As String) As Boolean
    On Error GoTo Error_Handler
    #Const ScriptControl_EarlyBind = False    'Should normally be in the Module header
    #If ScriptControl_EarlyBind = True Then
        Dim oSC               As MSScriptControl.ScriptControl

        Set oSC = New ScriptControl
    #Else
        Static oSC            As Object

        Set oSC = CreateObject("ScriptControl")
    #End If
    Dim sOutput    'As Boolean
    Dim sJSON                 As String
    Dim sEscapedJSON          As String
    Dim sJS                   As String
    Dim obj                   As Object

    ' Minimal file validation
    If Dir(sFile) = "" Then Exit Function    ' File does not exist

    ' Could check if 1st character is { if we wanted to

    ' Get the content of the file in question
    sJSON = ReadFileAsText(sFile)

    If Not oSC Is Nothing Then
        With oSC
            .Language = "JScript"
            Set obj = oSC.Eval("(" & sJSON & ")")
            JSON_ISValidFile = True
        End With
    End If

Error_Handler_Exit:
    On Error Resume Next
    Set obj = Nothing
    Set oSC = Nothing
    Exit Function

Error_Handler:
    Select Case Err.Number
        Case 1002, 1006, 1028    ' Syntax error / Expected identifier, string or number
            ' There may be more err.number to add here as I've just used this in a limited capacity
        Case Else
            MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
                   "Error Source: JSON_ISValidFile" & vbCrLf & _
                   "Error Number: " & Err.Number & vbCrLf & _
                   "Error Description: " & Err.Description & _
                   Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
                   , vbOKOnly + vbCritical, "An Error has Occurred!"
    End Select
    Resume Error_Handler_Exit
End Function

'---------------------------------------------------------------------------------------
' Procedure : ADODB_ReadFileAsText
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : 
' Purpose   : This code opens a UTF-8 encoded text file and reads its entire contents
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - 
' Req'd Refs: Late Binding  -> None required
'             Early Binding -> Microsoft ActiveX Data Objects x.x Library
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFile     : Fully qualified path and filename to read
'
' Usage:
' ~~~~~~
' ADODB_ReadFileAsText("C:\Users\Dev\Desktop\Booking.json")
'   Returns -> the content of the file in question
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2012-05-14
' 2         2025-04-21              Initial Public Release
'---------------------------------------------------------------------------------------
Function ADODB_ReadFileAsText(ByVal sFile As String) As String
    On Error GoTo Error_Handler
    #Const ADODBStream_EarlyBind = False    'Should normally be in the Module header
    #If ADODBStream_EarlyBind = True Then
        Dim oADODBStream As ADODB.stream

        Set oADODBStream = New ADODB.stream
    #Else
        Static oADODBStream As Object

        Set oADODBStream = CreateObject("ADODB.Stream")
        Const adTypeText = 2
    #End If

    With oADODBStream
        .Type = adTypeText
        .Charset = "utf-8" 'You may need to change this depending on the file
        .Open
        .LoadFromFile sFile
        ADODB_ReadFileAsText = .ReadText
        .Close
    End With

Error_Handler_Exit:
    On Error Resume Next
    Set oADODBStream = Nothing
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Source: ADODB_ReadFileAsText" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

¡Ahora, el principal inconveniente aquí es el hecho de que ScriptControl solo está disponible en instalaciones de 32 bits!

Posibles otros enfoques

Al igual que con los archivos XML, hay otras técnicas posibles que podríamos usar, como verificar la extensión del archivo.

Validación de extensión de archivo

Al igual que expliqué en mi artículo de XML, las extensiones no garantizan el contenido del archivo real, sin embargo, si se encuentra en un entorno controlado y cree que simplemente puede confiar en la extensión del archivo para garantizar el contenido JSON de un archivo, entonces podría salirse con la suya simplemente hacer algo como:

'---------------------------------------------------------------------------------------
' Procedure : File_HasExtension
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : 
' Purpose   : Validate whether a file has the specified extension
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - 
' Req'd Refs: None required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFile             : Fully qualified path and filename to validate
' sFileExtension    : File extension to check for
'                       Recommend including the . in the validation
'
' Output Variables:
' ~~~~~~~~~~~~~~~~~
' Boolean:  True    -> Has the specified file extension
'           False   -> Does NOT have the specified file extension
'
' Usage:
' ~~~~~~
' File_HasExtension("C:\Users\Daniel\Downloads\note.xMl", ".xml")
'   Returns -> True
'
' File_HasExtension("C:\Temp.txtl", ".xml")
'   Returns -> False
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2005-07-13
' 2         2025-04-22              Update Function Header
'                                   Update Error Handler
'---------------------------------------------------------------------------------------
Function File_HasExtension(ByVal sFile As String, _
                           ByVal sFileExtension As String) As Boolean
    On Error GoTo Error_Handler

    If Right(sFile, Len(sFileExtension)) = sFileExtension Then File_HasExtension = True

Error_Handler_Exit:
    On Error Resume Next
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Source: File_HasExtension" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

Donde puedes simplemente hacer:

If Not File_HasExtension("C:\Users\Daniel\Downloads\booking-2390.json", ".json") Then
   ' Not a JSON file extension
    Exit Sub/Function
End If

' Continue because the JSON file had the proper extension

Usando el control moderno del navegador web

Otra opción sería usar (oculto si lo desea) un MWBC para usar json.parse () a través de él.

Use una biblioteca JSON

Otra gran opción sería usar una biblioteca JSON como:

Luego puede usar las funciones incorporadas para probar la cadena JSON. Para hacerlo, puede crear una función simple como:

'---------------------------------------------------------------------------------------
' Procedure : JSON_JsonConverter_ISValidFile
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : 
' Purpose   : Validate whether the file is a properly formatted JSON file or not
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - 
' Req'd Refs: None required
' Dependencies: ReadFileAsText()
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFile             : Fully qualified path and filename to validate
'
' Output Variables:
' ~~~~~~~~~~~~~~~~~
' Boolean:  True    -> Is a JSON file
'           False   -> Is NOT a JSON file
'
' Usage:
' ~~~~~~
' ? JSON_JsonConverter_ISValidFile("C:\Users\Daniel\Downloads\json02.json")
'   Returns -> True/False
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2025-04-21
'---------------------------------------------------------------------------------------
Function JSON_JsonConverter_ISValidFile(ByVal sFile As String) As Boolean
    On Error GoTo Error_Handler
    Dim sFileContent          As String
    Dim oJson                 As Object
    
    ' Retrieve the file's contents
    sFileContent = ReadFileAsText(sFile)

    ' Try parsing the JSON
    Set oJson = JsonConverter.ParseJson(sFileContent)
    JSON_JsonConverter_ISValidFile = True

Error_Handler_Exit:
    On Error Resume Next
    Set oJson = Nothing
    Exit Function

Error_Handler:
    Resume Error_Handler_Exit
End Function

'---------------------------------------------------------------------------------------
' Procedure : ADODB_ReadFileAsText
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : 
' Purpose   : This code opens a UTF-8 encoded text file and reads its entire contents
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - 
' Req'd Refs: Late Binding  -> None required
'             Early Binding -> Microsoft ActiveX Data Objects x.x Library
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFile     : Fully qualified path and filename to read
'
' Usage:
' ~~~~~~
' ADODB_ReadFileAsText("C:\Users\Dev\Desktop\Booking.json")
'   Returns -> the content of the file in question
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2012-05-14
' 2         2025-04-21              Initial Public Release
'---------------------------------------------------------------------------------------
Function ADODB_ReadFileAsText(ByVal sFile As String) As String
    On Error GoTo Error_Handler
    #Const ADODBStream_EarlyBind = False    'Should normally be in the Module header
    #If ADODBStream_EarlyBind = True Then
        Dim oADODBStream As ADODB.stream

        Set oADODBStream = New ADODB.stream
    #Else
        Static oADODBStream As Object

        Set oADODBStream = CreateObject("ADODB.Stream")
        Const adTypeText = 2
    #End If

    With oADODBStream
        .Type = adTypeText
        .Charset = "utf-8" 'You may need to change this depending on the file
        .Open
        .LoadFromFile sFile
        ADODB_ReadFileAsText = .ReadText
        .Close
    End With

Error_Handler_Exit:
    On Error Resume Next
    Set oADODBStream = Nothing
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Source: ADODB_ReadFileAsText" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

Luego, simplemente puede usar la función en su código como:

If Not JSON_JsonConverter_ISValidFile ("C:\Users\Daniel\Downloads\booking-2390.json") Then
   ' Not a valid JSON file
    Exit Sub/Function
End If

' Continue because the JSON file passed validation

Además, si está buscando validar un archivo para ver si está en un formato JSON válido, es probable que desee trabajar con él más y una biblioteca como el JsonConverter facilitará enormemente dicho trabajo. Por lo tanto, esta es una gran opción, ya que facilita mucho más que simplemente validar el archivo.

Por lo tanto, allí lo tiene múltiples enfoques posibles que puede implementar para validar si un archivo es realmente un archivo JSON, o no. Ahora, todo lo que tiene que hacer es elegir el que lo haga feliz y se adapte a sus necesidades de desarrollo.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba