domingo, 29 de abril de 2012

EL protocolo DDE

El protocolo de intercambio dinámico de datos DDE (Dynamic Data Exchange) es uno de los métodos de comunicación entre procesos que permite intercambiar datos entre aplicaciones de Windows. El protocolo DDE está basado en el sistema de mensajería construido por Windows.

EL vínculo DDE comprende tres fases principales:

1º.- Inicialización: la aplicación destino busca la aplicación fuente y establece con ella un canal de comunicación (vinculo).

La función DDEinitiate: Permite inicia la comunicación entre dos aplicaciones.

2º.- Conversación: se intercambian los datos en el canal.

La función DDE: Permite establecer la conversación.
La función DDESend: Envía un elemento de información a la aplicación.
La función DDEPoke: Envía información a la aplicación fuente por un canal abierto.
La función DDERequest: pide información a la aplicación fuente.
La función DDEExcute: envía una cadena de comandos a la aplicación vinculada.

3º.- Clausura: cierra el canal de comunicación.

La función DDETerminate: cierra el canal de información DDE.
La función DDETerminateAll: cierra todos los canales de comunicación DDE.

El siguiente ejemplo muestra como copiar celdas Excel al principio de un documento Word.


Sub transferirInforme()
Dim canal As Long
'Inicializacion
    canal = Application.DDEInitiate("WinWord", "C:\Users\Jose Luis\Desktop\PruebaDDE\presupuesto.docx")
    Worksheets(1).Range("D8:E12").Select
'Conversacion
    Application.DDEPoke canal, "\StartOfDoc", Selection
'Clausura
    Application.DDETerminate canal
End Sub

“\ StartOfDoc” es un marcador predefinido en Word.

domingo, 22 de abril de 2012

Invalidar la X del UserForm

Alguna vez nos hemos preguntado como podría impedir que el usuario pulse el botón de cerrar el formulario.
Para eliminar el botón de cerrar de una barra de titulo de un UserForm, se necesita complejas funciones API como las que vimos en el post anterior. Una solución mucho mas sencilla consiste en interceptar todos los intentos de cerrar el UserForm por medio de un procedimiento de eventos “UserForm_QueryClose” en el modulo de código del UserForm.

El siguiente ejemplo impide al usuario cerrar el formulario pulsando el botón de Cerrar:

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = vbFormControlMenu Then
        Cancel = True
    End If
End Sub

Cuando se intenta cerrar el formulario, utilizamos el procedimiento de evento QueryClose para establecer la propiedad Cancel a True, deteniendo el proceso de cierre.

domingo, 8 de abril de 2012

Truco para UserForm

Excel no ofrece de ninguna manera mostrar directamente un formulario sin su barra de titulo, pero esto lo podemos hacer realidad gracias a la utilización de funciones API.

Que es API??

API es un acrónimo de Interfaz de programación de aplicaciones, el conjunto de comandos que utiliza una aplicación para solicitar y realizar servicios de nivel inferior del sistema operativo del PC.

Cuando necesites capacidades que vayan más allá del lenguaje y los controles comunes proporcionados por Microsoft Visual Basic, puedes llamar directamente a los procedimientos incluidos en las bibliotecas de vínculos dinámicos (DLL, Dinamyc Link Libraries). Al llamar a estos procedimientos, podrás tener acceso a los miles de procedimientos que constituyen la espina dorsal del sistema operativo Microsoft Windows, así como a rutinas creadas en otros lenguajes.

Para mostrar un UserForm sin barra de titulo necesitamos cuatro funciones API:
  • Function GetWindowLong
  • Function SetWindowLong
  • Function DrawMenuBar
  • Function FindWindowA 
Que declararemos de forma Privada dentro de nuestro formulario, luego las haremos llamar desde el procedimiento de iniciación del formulario (UserForm_Initialize).

El código quedaría más o menos de la siguiente forma,

Option Explicit
Const GWL_STYLE = -16
Const WS_CAPTION = &HC00000
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function FindWindowA Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Sub UserForm_Initialize()
    Dim lngWindow As Long, lFrmHdl As Long
    lFrmHdl = FindWindowA(vbNullString, Me.Caption)
    lngWindow = GetWindowLong(lFrmHdl, GWL_STYLE)
    lngWindow = lngWindow And (Not WS_CAPTION)
    Call SetWindowLong(lFrmHdl, GWL_STYLE, lngWindow)
    Call DrawMenuBar(lFrmHdl)
End Sub

Un problema que se nos puede presentar al utilizar un formulario sin barra de titulo es que no tenemos manera de cerrarlo si no creamos un botón de cerrar o cambiar su tamaño.



Si quieres aprender mas sobre API pincha aquí.

domingo, 1 de abril de 2012

Formas

Excel utiliza el grupo Formas o “Shapes”, al que se accede seleccionando insertar>>Formas para insertar una forma “Shape” a una hoja de trabajo.

Shapes (objeto)  es la colección de todos los objetos Shape de la hoja especificada, cada objeto Shape representa un objeto de la capa de dibujo, como una autoforma, una forma libre, un objeto OLE o una imagen.

El número del nombre de la forma varía, dependiendo de cuantas formas iguales se haya insertado, por ejemplo si se han incrustado dos rectángulos, el nombre del segundo seria “2 Rectangle”.

Usaremos Shapes(índice), donde índice es el nombre o número de índice de la forma, para obtener un solo objeto Shape.

El siguiente procedimiento crea una forma con una textura y aplica algunos efectos y sombras.

Sub ObShapes()
Dim shp As Shape
Set shp = ActiveSheet.Shapes.AddShape(Type:=msoShapeMathMultiply, _
Left:=100, Top:=10, Width:=200, Height:=200)
    With shp
        .Line.Visible = False
        .ThreeD.Visible = True
        .ThreeD.Depth = 60
        .ThreeD.RotationY = 10
        .Shadow.Visible = True
        .Shadow.Transparency = 0.8
        .Shadow.Blur = 12
        .Fill.ForeColor.RGB = RGB(255, 0, 0)
    End With
End Sub

Al trabajar con formas es preferible que el código realice varias acciones, por lo tanto es eficiente crear una variable de objeto.

Nuestro ejemplo quedaría más o menos como la siguiente imagen: