** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - Extraer el número de páginas de un documento
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradoExtraer el número de páginas de un documento

 Responder Responder Página  12>
Autor
Mensaje
RobertoCarlos Ver desplegable
Habitual
Habitual


Unido: 12/Marzo/2013
Localización: Bolivia
Estado: Sin conexión
Puntos: 168
Enlace directo a este mensaje Tema: Extraer el número de páginas de un documento
    Enviado: 30/Mayo/2023 a las 16:59
Buenos días a todos los colaboradores, estoy con un prqueño problema por eso recurro a ustedes, 
Que necesito
Necesito en un campo de texto de un formulario access al momento de cargarse el documento en el control, se me agreguen la cantidad de paginas de ese documento. 
Que tengo hecho hasta el momento
Private Function ContarPaginasPDF(rutaArchivo As String) As Integer
    Dim pdf As Object
    'Set pdf = CreateObject("AcroExch.PDDoc")
    Set pdf = CreateObject("AcroPDF.PDDoc")
    If pdf.Open(rutaArchivo) Then
        ContarPaginasPDF = pdf.GetNumPages()
        pdf.Close
    End If
    
    Set pdf = Nothing
End Function

Private Sub btnCargarDocumento_Click()
    Dim rutaArchivo As String
    Dim numPaginas As Integer
    
    ' Abre un cuadro de diálogo para seleccionar el archivo PDF
    With Application.FileDialog(1) ' 1 para abrir archivos
        .Title = "Seleccionar documento PDF"
        .Filters.Clear
        .Filters.Add "Archivos PDF", "*.pdf"
        If .Show = -1 Then
            rutaArchivo = .SelectedItems(1)
            Me.txtRuta.Value = rutaArchivo
            ' Asigna la ruta del archivo seleccionado al control ActiveX
            Me.WebBrowserControl.Navigate rutaArchivo
            'numPaginas = ContarPaginasPDF(rutaArchivo)
            'MsgBox "El archivo contiene " & numPaginas & " páginas."
        End If
    End With
End Sub

El control que estoy utilizando es el Microsoft Web Brouser, 

Con esta línea Set pdf = CreateObject("AcroPDF.PDDoc") me sale el siguiente error "Se ha producido un error 429 en tiempo de ejecución" EL COMPONENTE ACTIVEX NO PUDO CREAR EL OBJETO

Con esta línea Set pdf = CreateObject("AcroExch.PDDoc") , Me sale el error interfaz no compatible, 
'
Tengo esta biblioteca AcroPDF.dll en el equipo en la carpeta system32

Ya no se como mas lo puedo solucionar por favor me pueden ayudar a conseguir una solución?

Muchas gracias por sus ideas y soluciones 

Roberto
Arriba
happy Ver desplegable
Moderador
Moderador


Unido: 29/Enero/2005
Localización: España
Estado: Sin conexión
Puntos: 3192
Enlace directo a este mensaje Enviado: 31/Mayo/2023 a las 13:26
Hola Roberto Carlos, en principio, el error que te aparece quiere decir que no tienes instalado en el PC desde se ejecuta ese código los componentes necesarios. El código que haces servir, concretamente la función ContarPaginasPDF, necesita que tengas instalada alguna versión del Adobe Acrobat, no el Reader, ese no, pues esa versión no permite hacer este tipo de cosas, supongo que debe ser alguna versión Standard o Profesional o algo así, o si es más reciente, imagino que será la versión DC (no estoy al tanto de las versiones del Acrobat)

En el caso de que no tengas acceso a esos programas de Adobe, he encontrado un método alternativo en este enlace: https://stackoverflow.com/questions/45015108/how-to-get-the-number-of-pages-in-a-pdf-document-using-vba

De ahí he sacado una función que postean, la he retocado un poco y parece que funciona bien (aunque no sé si funcionará para todas las versiones de pdfs)

Function fNumberOfPages_in_PDF_File(vFileName As String) As Long
Dim xStr As String
Dim xFileNum As Long
Dim RegExp As Object

    '--- Number of Pages =0 if the file is not a PDF file
    If Not vFileName Like "*.pdf" Then
        fNumberOfPages_in_PDF_File = 0
        Exit Function
    End If

    '--- Count the number of pages in Pdf File
    xStr = ""
    Set RegExp = CreateObject("VBscript.RegExp")
    RegExp.Global = True
    RegExp.Pattern = "/Type\s*/Page[^s]"
    xFileNum = FreeFile
    Open (vFileName) For Binary As #xFileNum
        xStr = Space(LOF(xFileNum))
        Get #xFileNum, , xStr
    Close #xFileNum

    fNumberOfPages_in_PDF_File = RegExp.Execute(xStr).Count
    
End Function

EDITO: lo he probado un poco más con diferentes PDFs y en la mayoría funciona bien, pero algunos no, me devuelve 0 páginas cuando tiene 1 o 2. Parece que depende un poco de cómo haya sido generado el PDF. Pero bue ...

Espero que te sirva


Editado por happy - 31/Mayo/2023 a las 13:33
Saludos,

Juan M. Afan de Ribera
Arriba
McPegasus Ver desplegable
Habitual
Habitual


Unido: 02/Abril/2007
Localización: España
Estado: Sin conexión
Puntos: 81
Enlace directo a este mensaje Enviado: 31/Mayo/2023 a las 14:07
Hola Roberto Carlos,

    intPagesDoc01 = AcroPDDoc01.GetNumPages

Yo uso este código, es posible que si quitas los paréntesis te funcione -> GetNumPages()

Ya nos confirmas.

Rafel.
Rafael [McPegasus]
Valencia
www.mcpegasus.net
..:: Tu Access, Mi Pasión ::..
Arriba
happy Ver desplegable
Moderador
Moderador


Unido: 29/Enero/2005
Localización: España
Estado: Sin conexión
Puntos: 3192
Enlace directo a este mensaje Enviado: 31/Mayo/2023 a las 14:48
Rafa, si le sale el mensaje de error 429 en la línea que él indica, entonces es lo que le digo yo, por mucho que corrija los paréntesis del GetNumPages, ya que no llega a ejecutar ninguna de las líneas siguientes

Geek Wink
Saludos,

Juan M. Afan de Ribera
Arriba
javier.mil Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 10/Agosto/2005
Localización: España
Estado: Sin conexión
Puntos: 4830
Enlace directo a este mensaje Enviado: 01/Junio/2023 a las 10:55
Buenas

He probado el código aportado por Juan (Happy) donde para PDF con menos de 1.300 paginas funciona bien  ,....... peroooo

Para PDF's con mas de 2.300 Paginas falla (da error de desbordamiento de memoria) . No sabría decir con exactitud donde estaría el limite.
Arriba
happy Ver desplegable
Moderador
Moderador


Unido: 29/Enero/2005
Localización: España
Estado: Sin conexión
Puntos: 3192
Enlace directo a este mensaje Enviado: 01/Junio/2023 a las 11:12
Publicado originalmente por javier.mil javier.mil escribió:

Buenas

He probado el código aportado por Juan (Happy) donde para PDF con menos de 1.300 paginas funciona bien  ,....... peroooo

Para PDF's con mas de 2.300 Paginas falla (da error de desbordamiento de memoria) . No sabría decir con exactitud donde estaría el limite.

En realidad no es un código mío. Lo he rescatado de un hilo de por ahí y retoqué la función. Lo puse porque me pareció curioso el método y en principio con unos cuantos documentos me funcionó correctamente, pero luego lo volví a probar y ví que para algunos casos no lo hacía bien. Se basa en editar el pdf y buscar alguna coincidencia con el patrón /Type /Page, que por lo que he podido comprobar en los pdfs, se utiliza para determinar una página nueva ... pero he visto que esto a veces no se cumple. Seguramente porque dependerá del programa o lenguaje que se utilice para generar el pdf, que no siempre sigue las mismas reglas por lo que parece.

Lo que comentas del límite de 2.300 páginas (que aún así me parece una barbaridad, ya que ese pdf debe pesar un montón, no?) habría que ver en qué línea del código hace que pete y ver si se le puede aplicar una solución alternativa (todo tiene solución si se le aplica algo de ingenio)


Editado por happy - 01/Junio/2023 a las 11:16
Saludos,

Juan M. Afan de Ribera
Arriba
javier.mil Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 10/Agosto/2005
Localización: España
Estado: Sin conexión
Puntos: 4830
Enlace directo a este mensaje Enviado: 01/Junio/2023 a las 12:32
El código peta en esta Linea       
 Get #xFileNum, , xStr

Runtime Error 7
Out of Memory


Arriba
happy Ver desplegable
Moderador
Moderador


Unido: 29/Enero/2005
Localización: España
Estado: Sin conexión
Puntos: 3192
Enlace directo a este mensaje Enviado: 01/Junio/2023 a las 20:09
Javier, ¿puedes preguntar con ese fichero con 1.300 páginas el nº resultante de LOF(xFileNum)? Imagino que será un número bastante alto que hace que falle la instrucción Get. Esa instrucción Get viene del antiguo BASIC y podría ser que no contemplaran números excesivamente grandes (aunque sólo lo supongo). Si la cosa fuera por ahí, entonces en vez de utilizar Open y Get # se podría utilizar un objeto TextStream del FileSystemObject y utilizar ReadAll para obtener esa cadena de texto con la cual calcular el nº de coincidencias para los números de página.

Si quieres probar a sustituir la parte del Open y Get con otra que utilice FileSystemObject, OpenTextFile y ReadAll ... yo no dispongo que ficheros tan grandes como ese que mencionas para probar. A ver qué pasa
Saludos,

Juan M. Afan de Ribera
Arriba
RobertoCarlos Ver desplegable
Habitual
Habitual


Unido: 12/Marzo/2013
Localización: Bolivia
Estado: Sin conexión
Puntos: 168
Enlace directo a este mensaje Enviado: 01/Junio/2023 a las 21:02
He probado este código, desde el evento de un boton, y justo a la primera me quedo perfecto.
les agradezco a todos por el aporte.
Dios los bendiga y les compense el tiempo que gastan ayudando a los demas
Cierro el hilo

Roberto
Arriba
javier.mil Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 10/Agosto/2005
Localización: España
Estado: Sin conexión
Puntos: 4830
Enlace directo a este mensaje Enviado: 01/Junio/2023 a las 22:49
Juan, he probado con

      Set objScrip = CreateObject("Scripting.FileSystemObject")
      If objScrip.FileExists(vFileName) = True Then
            Set objFichero = objScrip.OpenTextFile(vFileName, 1)
            strCadena = objFichero.ReadAll
            objFichero.Close
      End If

Y el error es exactamente el mismo,

Runtime Error 7
Out of Memory

En cuanto a lo  que preguntabas sobre el numero resultante en LOF(xFileNum) es 243466232

El PDF son imágenes scaneadas y No es texto puro y duro ,...... quizás sea el problema ,..... pero ni idea ....

 
Arriba
happy Ver desplegable
Moderador
Moderador


Unido: 29/Enero/2005
Localización: España
Estado: Sin conexión
Puntos: 3192
Enlace directo a este mensaje Enviado: 02/Junio/2023 a las 08:43
Pues entonces es lo que imaginaba, veo que si intento esto:

strCadena = Space(243466232)

me aparece el error 14 Espacio para cadenas insuficiente. El error en nuestro caso puede ser que se produzca al intentar poner todo ese número de caracteres en la variable o que la instrucción ReadAll o el Get de antes no es capaz de abarcar es número.

En este caso lo único que se me ocurre es ampliar el procedimiento de la siguiente manera:

- En vez de declarar una variable String para recuperar el contenido del fichero, declarar una matriz dinámica
- En principio, intentar recuperar la información con ReadAll o Get en el primer elemento de la matriz. Si todo va bien (la mayoría de las veces), estupendo, ejecutar la función como hasta ahora
- Si salta el error de marras (el 7), entonces cambiar la estrategia e ir recuperando la información línea a línea hasta que salte de nuevo. En ese punto, cazar el error y seguir recuperando la información en el siguiente elemento de la matriz ... y seguir con la misma técnica hasta que se haya recuperado la totalidad del fichero. 
- Al final, hacer un bucle que recorra los elementos de la matriz y vaya acumulando la suma de RegExp.Execute(xStr(n)).Count en una variable tipo Double (por si acaso). Al terminar el contenido de esa variable será el resultado de la función con el número de páginas del pdf

Smile
Saludos,

Juan M. Afan de Ribera
Arriba
javier.mil Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 10/Agosto/2005
Localización: España
Estado: Sin conexión
Puntos: 4830
Enlace directo a este mensaje Enviado: 03/Junio/2023 a las 19:02

Después de realizar múltiples pruebas aleatorias con distintos tamaños de archivos PDF, parece que este código podría funcionar….

La siguiente función es una combinación de fragmentos de código de diferentes autores, ya que ninguno de ellos funcionaba correctamente, especialmente para archivos de gran tamaño.

Pruébalo … a ver que tal ….Sin embargo, es importante tener en cuenta que no ha sido testado completamente y es posible que existan errores (bugs).


Function funContarPaginasPDF(PonFichero As String) As Integer
      On Error GoTo Err_Local
      Rem www.accessdemo.info

      Dim objRegExp As Object
      Dim strInput As String
      Dim strNumPages As String
      Dim strRetVal As String
      Dim intFileNum As Integer
      Dim intPosN1 As Integer
      Dim intPosN2 As Integer
      Dim intPosCount1 As Integer
      Dim intPosCount2 As Integer


      If LCase(Right(PonFichero, 3)) <> "pdf" Then
            funContarPaginasPDF = 0
            Exit Function
      End If

      intFileNum = FreeFile
      Open PonFichero For Binary Lock Read Write As #intFileNum


      Set objRegExp = CreateObject("VBscript.RegExp")
      objRegExp.Global = True
      objRegExp.Pattern = "/Type\s*/Page[^s]"


      On Error Resume Next
      strRetVal = Space(LOF(intFileNum))
      Get #intFileNum, , strRetVal
      strNumPages = objRegExp.Execute(strRetVal).Count
      On Error GoTo Err_Local


      If strNumPages = "" Then

            Do Until EOF(intFileNum)
                  Input #1, strInput
                  strInput = UCase(strInput)
                  intPosN1 = InStr(1, strInput, "/N ") + 3
                  intPosN2 = InStr(intPosN1, strInput, "/")
                  intPosCount1 = InStr(1, strInput, "/COUNT ") + 7
                  intPosCount2 = InStr(intPosCount1, strInput, "/")

                  If intPosN1 > 3 Then
                        strNumPages = Mid(strInput, intPosN1, intPosN2 - intPosN1)
                        Exit Do
                  End If

                  If intPosCount1 > 7 Then
                        strNumPages = Mid(strInput, intPosCount1, intPosCount2 - intPosCount1)
                        Exit Do
                  End If

            Loop

      End If


Close_Local:
      Set objRegExp = Nothing
      Close #intFileNum
      funContarPaginasPDF = CInt(strNumPages)

Exit_Local:
      On Error GoTo 0
      Exit Function

Err_Local:
      MsgBox Err.Description, vbCritical, "Error N°:  " & Err.Number
      Resume Exit_Local
End Function





Editado por javier.mil - 03/Junio/2023 a las 19:28
Arriba
javier.mil Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 10/Agosto/2005
Localización: España
Estado: Sin conexión
Puntos: 4830
Enlace directo a este mensaje Enviado: 03/Junio/2023 a las 20:19
Olvide comentar que No es necesario activar ninguna Referencia especifica de Acrobat o similar...
Arriba
happy Ver desplegable
Moderador
Moderador


Unido: 29/Enero/2005
Localización: España
Estado: Sin conexión
Puntos: 3192
Enlace directo a este mensaje Enviado: 04/Junio/2023 a las 12:04
Hola, yo estoy intentando crear un pdf suficientemente grande para que me pete la función. De momento estoy insertando 150.000 veces el párrafo

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris iaculis ex turpis, vel feugiat tortor semper non. Pellentesque sodales nisi elementum magna cursus blandit. Sed ut quam odio. Quisque sodales malesuada mi id luctus. Donec pulvinar vehicula elit vel mollis. Donec dignissim vehicula odio ut suscipit. Phasellus mattis sollicitudin nibh, quis consequat eros ornare id. Fusce ornare nec mi quis commodo. Sed tincidunt commodo risus. Aliquam facilisis fermentum mi eget dignissim. In egestas est nisi, nec vestibulum ante facilisis sit amet. Vestibulum finibus, orci nec egestas efficitur, arcu arcu iaculis lorem, sed consequat velit nisi eget mauris. Quisque nec nisl tristique odio pretium laoreet. Nullam sed laoreet sem, in auctor justo. Phasellus eleifend porta porta. Integer convallis velit sit amet mattis sagittis.

en un documento Word y luego lo convertiré en un PDF. Ya lo había hecho antes y había conseguido tener un PDF con más de 7.000 páginas con este texto, pero la función original no peta, ya que apenas ha de cargar 20.000.000 de caracteres y según parece el asunto petará cuando llegue a unos 200.000.000 de caracteres, según lo que apuntaba en una de las respuestas.

Haré la prueba cuando llegue ahí, pero tampoco me mataré, pues veo que esta función cubrirá la práctica totalidad de los casos que normalmente se necesitarán. También comenté que en algunas ocasiones, la función no iba bien ya que según como se haya generado el pdf, esa estructura de cadena buscada (la del Type/Page) ni siquiera consta dentro del documento. Por ejemplo hice la prueba con 2 o 3 pdfs que tenía por ahí y que eran la copia de entradas para alguna peli de cine y la función me devolvía 0 patatero cuando en realidad tenía 2, 3 o 4 páginas. Con ese tipo de PDF no chutaba bien
Saludos,

Juan M. Afan de Ribera
Arriba
Mihura Ver desplegable
Administrador
Administrador
Avatar

Unido: 06/Mayo/2005
Localización: En la dehesa
Estado: Sin conexión
Puntos: 14017
Enlace directo a este mensaje Enviado: 04/Junio/2023 a las 12:27
¿Puede ser la herramienta con la que creas el PDF?
Supongo que será lo mismo crear un PDF desde Word con la utilidad propia de Office, que con la impresora virtual Acrobat, que con el CutePDF, etc.
Jesús Mansilla Castells.
Saludos desde Móstoles.

Access Aplicaciones
Tecsys.es
Arriba
 Responder Responder Página  12>
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable