Mensajes recientes

Páginas: [1] 2 3 ... 10
1
Varias / Redondear hacia arriba
« Último mensaje por xavi en Mayo 06, 2025, 10:33:38 am »
Palabras clave: redondear, arriba
Autor: Experiencia propia

Necesito emular el funcionamiento de MULTIPLO.SUPERIOR.MAT de Excel en Access. Dado que no encuentro una función o comando que lo haga, me creo una pequeña función:


Código: [Seleccionar]
Function RedondeaArriba(dblNumero As Double) As Long
    ' Función que toma un número con decimales y lo devuelve sin decimales como Long
   
    RedondeaArriba = Int(dblNumero) + Abs(dblNumero > Int(dblNumero))

End Function

2
Tablas / Como asignar un valor específico a un registro
« Último mensaje por xavi en Abril 15, 2025, 04:41:21 pm »
Por necesidades "x" se requiere introducir un registro en una determinada posición de una tabla con un determinado valor en el campo autonumérico. No existe una forma sencilla de hacerlo así que debemos tirar de astucia.

Happy nos enseña un par de funciones que, bien colocadas en otro procedimiento, pueden obtener el resultado esperado.

Yo creo que hay que hacerlo en 3 pasos:

GetSeed para saber el próximo autonumérico (y guardarlo para el paso 3)
SetSeed para establecer el siguiente registro
(insertar el registro)
SetSeed con el valor guardado en paso 1


 Obtener el siguiente autonumérico
Código: [Seleccionar]
Public Function GetSeed(Tabla As String, Campo As String) As Long
Dim cat As Object
   
    On Error Resume Next
    Set cat = CreateObject("ADOX.Catalog")
    ' para otra base de datos externa a la actual
    ' sustituir CurrentProject.Connection por objecto ADODB.Connection ADODB
    ' conectado a la base externa
    cat.ActiveConnection = CurrentProject.Connection
    GetSeed = cat.Tables(Tabla).columns(Campo).Properties("Seed")
    Set cat = Nothing
    On Error GoTo 0
   
End Function

 Establecer el siguiente autonumérico
Código: [Seleccionar]
Public Function SetSeed(Tabla As String, _
                        Campo As String, _
                        SiguienteNumero As Long, _
                        Optional Intervalo As Long) As Boolean
Dim cat As Object
   
    On Error Resume Next
    Set cat = CreateObject("ADOX.Catalog")
    ' para otra base de datos externa a la actual
    ' sustituir CurrentProject.Connection por objecto ADODB.Connection ADODB
    ' conectado a la base externa
    cat.ActiveConnection = CurrentProject.Connection
    cat.Tables(Tabla).columns(Campo).Properties("Seed") = SiguienteNumero
    If Intervalo <> 0 Then
        cat.Tables(Tabla).columns(Campo).Properties("Interval") = Intervalo
    End If
    Set cat = Nothing
    On Error GoTo 0

End Function
3
General / Re:** ¿Referenciar o no referenciar?
« Último mensaje por xavi en Enero 11, 2025, 11:19:07 am »
Esta página no admite preguntas. Para ello referirse a www.mvp-access.com y presentar la duda allí.
4
General / ** ¿Referenciar o no referenciar?
« Último mensaje por Matthewfluip en Enero 08, 2025, 03:24:51 pm »
** ¿Qué pasaría si, en lugar de referenciar objetos o datos, simplemente los duplicamos en cada lugar donde se necesiten? ¿Sería una locura total o una solución ingeniosa para evitar problemas de sincronización y dependencias? ¿O acaso estamos subestimando el caos que esto podría generar en un sistema complejo?
5
Correo / Mail con firma
« Último mensaje por xavi en Diciembre 21, 2023, 01:47:29 pm »

Palabras clave: correo, firma
Autor: acilu55
Extraído de: MV-Access


REDACCION PROVISIONAL


Objetivo
Se preguntó como enviar mail con firma. En principio era con CDO (que desconocía que se podía hacer) y acilu55 propuso, mediante Outlook, la capacidad de utilizar una plantilla de mail con la firma:

Código: [Seleccionar]
Set OUTAPP = CreateObject("Outlook.Application")
Set OUTMAIL = OUTAPP.CreateItemFromTemplate(Application.CurrentProject.Path & "\oficio.oft")
 ' oficio.oft es una plantila de mail con la firma
With OUTMAIL
.To = mail
.cc = ""
.bcc = ""
.BodyFormat = olFormatHTML
           
.Subject = "asunto del envio"
adjunto1 = Application.CurrentProject.Path & "\factura.pdf"

.Attachments.Add (adjunto1)
6
Varias / Variables de entorno
« Último mensaje por xavi en Octubre 25, 2023, 11:35:21 pm »
Palabras clave: entorno, environ, variables
Autor: Sergio Alejandro Campos
Extraído de: EXCELeINFO



La necesidad surge al necesitar saber si existe una variable de entorno que devuelva el nombre del usuario "bonito" (que no existe) y no saber las posibles variables que se pueden consultar.

Sergio nos brinda este código (requiere un libro con una "Hoja1" y habilitado para macros


Código: [Seleccionar]
Sub MostrarVariables()
    'Declaramos variables
    '
    Dim i As Integer
    '
    i = 1
    '
    'Mientras el valor de Environ NO sea vacío, se obtiene el valor.
    While Environ(i) <> Empty
        '
        ActiveWorkbook.Sheets("Hoja1").Range("A8").Offset(i, 0).Value = Environ(i)
        '
        i = i + 1
        '
    Wend
    '
End Sub
7
Formularios / Re:Abrir copias de formulario
« Último mensaje por xavi en Julio 04, 2023, 01:55:01 pm »
Actualización tomando la info de Allen Browne Hay un ejemplo en esa URL

Para evitar problemas, utiliza una colección pública y un código en un módulo independiente.
El ejemplo de Allen toma un formulario llamado frmClient

Código: [Seleccionar]
Public clnClient As New Collection    'Instances of frmClient.
Function OpenAClient()
    'Purpose:    Open an independent instance of form frmClient.
    Dim frm As Form

    'Open a new instance, show it, and set a caption.
    Set frm = New Form_frmClient
    frm.Visible = True
    frm.Caption = frm.Hwnd & ", opened " & Now()

    'Append it to our collection.
    clnClient.Add Item:=frm, Key:=CStr(frm.Hwnd)

    Set frm = Nothing
End Function

Function CloseAllClients()
    'Purpose: Close all instances in the clnClient collection.
    'Note: Leaves the copy opened directly from database window/nav pane.
    Dim lngKt As Long
    Dim lngI As Long

    lngKt = clnClient.Count
    For lngI = 1 To lngKt
        clnClient.Remove 1
    Next
End Function

La segunda función CloseAllClients() muestra cómo cerrar estas instancias eliminándolas de nuestra colección. Pero si el usuario cierra una instancia con la interfaz normal, debemos eliminar esa instancia de nuestra colección. Eso se hace en el evento Cerrar del formulario frmClient de esta manera:

Código: [Seleccionar]
Private Sub Form_Close()
    'Purpose: Remove this instance from clnClient collection.
    Dim obj As Object        'Object in clnClient

    Dim blnRemove As Boolean  'Flag to remove it.

    'Check if this instance is in the collection.
    For Each obj In clnClient
        If obj.Hwnd = Me.Hwnd Then
            blnRemove = True
            Exit For
        End If
    Next

    'Deassign the object and remove from collection.
    Set obj = Nothing
    If blnRemove Then
        clnClient.Remove CStr(Me.Hwnd)
    End If
End Sub
8
Varias / Ejecutar cualquier acción de comando
« Último mensaje por xavi en Mayo 30, 2023, 06:54:29 pm »
Palabras clave: ejecutar, elemento, menú, commandbars, executemso
Autor: De aquí y de allá., pero la clave la dá René Nyffenegger
URL:Microsoft Learn
URL:René Nyffenegger
URL:github (también accesible desde URL anterior)


Objetivo
En ocasiones hay que ejecutar acciones de menú que no están accesibles mediante otros comandos de VBA. Para ello podemos invocar el método Application.CommandBars.ExecuteMso(idMSO)
El problema está en localizar los idMSO ya que la página de Microsoft es muy parca.
En la página de René se enlaza un repositorio de GitHub dónde se puede acceder a varias carpetas para distintas versiones de Office y, dentro de cada una, a una serie de ficheros Excel con todas las colecciones de idMSO

9
Fechas / Cálculo de dia laborable flexivo
« Último mensaje por xavi en Mayo 27, 2023, 05:55:40 pm »
Palabras clave: fecha, laborable, dia.lab.intl
Autor: xavi

Necesidad
Obtener que día será una fecha dada una fecha inicial, un número de laborales, un tipo de semana laboral y la utilización de una tabla de festivos.

Es una emulación (con ligeros cambios) de la función DIA.LAB.INTL de Excel

Código: [Seleccionar]
Function DiaLabIntl(dtmFechaInicial As Date, intDiasProceso As Integer, Optional strTipoSemanaLaboral As String = "0000011", Optional blnAplicaFestivos As Boolean = True) As Date
    ' Función análoga a la de Excel utilizando el tipo de semana laboral como cadena y un boolean para aplicar laborables y festivos
    ' En caso de aplicar festivos será necesario indicar el nombre de la tabla y el campo de la tabla que contiene la fecha
   
    ' La cadena de strTipoSemanaLaboral se establece con 7 ceros y unos. El cero indica laborable y el uno festivo.
    ' Así, "0000011" indica el fin de semana de sábado-domingo. Esa técnica nos permite gestionar (casi) cualquier combinación
   
   
    Const cTablaFestivos As String = "tblDatFestivos"
    Const cCampoFecha As String = "FechaFestiva"
   
    Dim dtmLaFecha  As Date
    Dim intdias As Integer
   
    ' Establecemos la fecha inicial
    dtmLaFecha = dtmFechaInicial
   
    ' Bucle sin condiciones
    Do
        ' Evaluamos si el día de la semana se ha estipulado como festivo.
        If Mid(strTipoSemanaLaboral, Weekday(dtmLaFecha, vbMonday), 1) = "1" Then
            ' Es un NO-laborable: no hacemos nada
        Else
            ' En este punto "parece" un laborable pero miramos si es festivo (si procede)
            If blnAplicaFestivos And DCount("*", cTablaFestivos, cCampoFecha & "= " & CLng(dtmLaFecha)) > 0 Then
                ' es un festivo: nada
            Else
                ' Ni es fin de semana, ni es festivo (sea porque no aplica, sea porque no lo es)
                intdias = intdias + 1
            End If
        End If
       
        ' Comprobamos si hemos alcanzado el limite de días
        If intdias >= intDiasProceso Then
            DiaLabIntl = dtmLaFecha
            Exit Function
        End If
        ' Aumentamos un día
        dtmLaFecha = DateAdd("d", 1, dtmLaFecha)
        ' Comprobación de seguridad
        If dtmLaFecha > DateAdd("d", intDiasProceso + 1000, dtmFechaInicial) Then
            MsgBox "Creo que nos hemos pasado de largo", vbExclamation
            DiaLabIntl = "01/01/1900"
            Exit Function
        End If
    Loop

End Function

10
Excel / Copiar un rango en el cuerpo de un correo electrónico
« Último mensaje por xavi en Mayo 15, 2023, 04:25:53 pm »
Palabras clave: Excel, rango, copia, outlook, correo
Autor: Ron De Bruin
Extraído de: Ron De Bruin

La necesidad surge de pegar el contenido de un rango de un fichero Excel abierto como parte del cuerpo de un correo electrónico.

Después de muchas vueltas y pruebas este código de Ron De Bruin soluciona el problema

Requiere una copia previa del rango o pasarle la dirección para que lo haga la función.


Código: [Seleccionar]
Function rngHTML(Rng As Object) ' Range
    Dim fso         As Object
    Dim ts          As Object
    Dim TempWB      As Object    ' Workbook
    Dim TempFile    As String
   
    TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
   
    '' copy the range and create a new workbook to paste the data into
    'Rng.Copy
   
   
    Set TempWB = xlsApp.Workbooks.Add(1)
    With TempWB.Sheets(1)
        .Cells(1).PasteSpecial Paste:=8
        .Cells(1).PasteSpecial xlPasteValues, , False, False
        .Cells(1).PasteSpecial xlPasteFormats, , False, False
        .Cells(1).Select
        .Application.CutCopyMode = False
        On Error Resume Next
        .DrawingObjects.Visible = True
        .DrawingObjects.Delete
        On Error GoTo 0
    End With

    '' publish the sheet to a htm file
    With TempWB.PublishObjects.Add( _
             SourceType:=xlSourceRange, _
             fileName:=TempFile, _
             Sheet:=TempWB.Sheets(1).Name, _
            Source:=TempWB.Sheets(1).UsedRange.Address, _
            HtmlType:=xlHtmlStatic)
        .Publish (True)
    End With

    '' read all data from the htm file into rngHTML
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
    rngHTML = ts.readall
    ts.Close
    rngHTML = Replace(rngHTML, "align=center x:publishsource=", "align=left x:publishsource=")

    TempWB.Close savechanges:=False
    '' delete the htm file we used in this function
    Kill TempFile

    Set ts = Nothing
    Set fso = Nothing
    Set TempWB = Nothing
End Function
Páginas: [1] 2 3 ... 10