then multiple funcion for examples comment vba hidden-features

multiple - Funciones ocultas de VBA



vba excel comment (16)

¿Qué características del lenguaje VBA están mal documentadas o simplemente no se usan con frecuencia?


Con un poco de trabajo, puede iterar sobre colecciones personalizadas como esta:

'' Write some text in Word first.'' Sub test() Dim c As New clsMyCollection c.AddItems ActiveDocument.Characters(1), _ ActiveDocument.Characters(2), _ ActiveDocument.Characters(3), _ ActiveDocument.Characters(4) Dim el As Range For Each el In c Debug.Print el.Text Next Set c = Nothing End Sub

Su código de colección personalizado (en una clase llamada clsMyCollection ):

Option Explicit Dim m_myCollection As Collection Public Property Get NewEnum() As IUnknown '' This property allows you to enumerate '' this collection with the For...Each syntax '' Put the following line in the exported module '' file (.cls)!'' ''Attribute NewEnum.VB_UserMemId = -4 Set NewEnum = m_myCollection.[_NewEnum] End Property Public Sub AddItems(ParamArray items() As Variant) Dim i As Variant On Error Resume Next For Each i In items m_myCollection.Add i Next On Error GoTo 0 End Sub Private Sub Class_Initialize() Set m_myCollection = New Collection End Sub


Diccionarios. ¡VBA es prácticamente inútil sin ellos!

Consulte Microsoft Scripting Runtime, use Scripting.Dictionary para cualquier tarea suficientemente complicada y viva feliz para siempre.

El Scripting Runtime también le proporciona el FileSystemObject, que también viene muy recomendado.

Comienza aquí, luego excava un poco ...

http://msdn.microsoft.com/en-us/library/aa164509%28office.10%29.aspx


El modelo de objetos VBE (Extensibilidad Visual Basic) es una característica menos conocida y / o infrautilizada. Le permite escribir código VBA para manipular códigos, módulos y proyectos de VBA. Una vez escribí un proyecto de Excel que reuniría otros proyectos de Excel de un grupo de archivos de módulos.

El modelo de objetos también funciona desde VBScript y HTA. Escribí una HTA a la vez para ayudarme a hacer un seguimiento de una gran cantidad de proyectos de Word, Excel y Access. Muchos de los proyectos utilizarían módulos de código comunes, y era fácil que los módulos "crecieran" en un sistema y luego se migraran a otros sistemas. Mi HTA me permite exportar todos los módulos en un proyecto, compararlos con las versiones en una carpeta común y fusionar rutinas actualizadas (usando BeyondCompare), y luego volver a importar los módulos actualizados.

El modelo de objetos VBE funciona de forma ligeramente diferente entre Word, Excel y Access, y desafortunadamente no funciona con Outlook en absoluto, pero aún ofrece una gran capacidad para administrar el código.


Escribiendo VBA. aparecerá una lista intellisense de todas las funciones y constantes incorporadas.


Este truco solo funciona en Access VBA, Excel y otros no lo permitirán. Pero puede hacer que un Módulo estándar esté oculto desde el navegador de objetos al agregar el nombre del Módulo con un guión bajo. El módulo solo será visible si cambia el navegador de objetos para mostrar objetos ocultos.

Este truco funciona con Enums en todas las versiones basadas en vb6 de VBA. Puede crear un miembro oculto de un Enum al incluir su nombre entre corchetes, y luego ponerle un guión bajo. Ejemplo:

Public Enum MyEnum meDefault = 0 meThing1 = 1 meThing2 = 2 meThing3 = 3 [_Min] = meDefault [_Max] = meThing3 End Enum Public Function IsValidOption(ByVal myOption As MyEnum) As Boolean If myOption >= MyEnum.[_Min] Then IsValidOption myOption <= MyEnum.[_Max] End Function

En Excel-VBA puede hacer referencia a las celdas encerrándolas entre paréntesis, los paréntesis también funcionan como un comando de evaluación que le permite evaluar la sintaxis de la fórmula:

Public Sub Example() [A1] = "Foo" MsgBox [VLOOKUP(A1,A1,1,0)] End Sub

También puede pasar datos sin procesar sin utilizar MemCopy (RtlMoveMemory) combinando LSet con tipos definidos por el usuario del mismo tamaño:

Public Sub Example() Dim b() As Byte b = LongToByteArray(8675309) MsgBox b(1) End Sub Private Function LongToByteArray(ByVal value As Long) As Byte() Dim tl As TypedLong Dim bl As ByteLong tl.value = value LSet bl = tl LongToByteArray = bl.value End Function

Los literales octales y hexadecimales son en realidad tipos sin firmar, ambos tendrán una salida -32768:

Public Sub Example() Debug.Print &H8000 Debug.Print &O100000 End Sub

Como se mencionó, pasar una variable dentro de paréntesis hace que sea pasada ByVal:

Sub PredictTheOutput() Dim i&, j&, k& i = 10: j = i: k = i MySub (i) MySub j MySub k + 20 MsgBox Join(Array(i, j, k), vbNewLine), vbQuestion, "Did You Get It Right?" End Sub Public Sub MySub(ByRef foo As Long) foo = 5 End Sub

Puede asignar una cadena directamente en una matriz de bytes y viceversa:

Public Sub Example() Dim myString As String Dim myBytArr() As Byte myBytArr = "I am a string." myString = myBytArr MsgBox myString End Sub

"Mid" también es un operador. Utilizándolo sobrescribe partes específicas de cadenas sin la concatenación de cadenas notoriamente lenta de VBA:

Public Sub Example1() ''''// This takes about 47% of time Example2 does: Dim myString As String myString = "I liek pie." Mid(myString, 5, 2) = "ke" Mid(myString, 11, 1) = "!" MsgBox myString End Sub Public Sub Example2() Dim myString As String myString = "I liek pie." myString = "I li" & "ke" & " pie" & "!" MsgBox myString End Sub


Funciones ocultas

  1. Aunque es "Básico", puede usar OOP - clases y objetos
  2. Puedes hacer llamadas a la API

Hay una característica importante pero casi siempre perdida de la declaración Mid (). Aquí es donde aparece Mid () en el lado izquierdo de una tarea en oposición a la función Mid () que aparece en el lado derecho o en una expresión.

La regla es que si la cadena de destino no es una cadena literal, y esta es la única referencia a la cadena de destino, y la longitud del segmento que se inserta coincide con la longitud del segmento que se reemplaza, entonces la cadena se tratará como mutable para la operación.

Qué significa eso? Significa que si construyes un gran informe o una enorme lista de cadenas en un solo valor de cadena, explotar esto hará que tu cadena de procesamiento sea mucho más rápida.

Aquí hay una clase simple que se beneficia de esto. Le da a su VBA la misma capacidad de StringBuilder que tiene .Net.

'' Class: StringBuilder Option Explicit Private Const initialLength As Long = 32 Private totalLength As Long '' Length of the buffer Private curLength As Long '' Length of the string value within the buffer Private buffer As String '' The buffer Private Sub Class_Initialize() '' We set the buffer up to it''s initial size and the string value "" totalLength = initialLength buffer = Space(totalLength) curLength = 0 End Sub Public Sub Append(Text As String) Dim incLen As Long '' The length that the value will be increased by Dim newLen As Long '' The length of the value after being appended incLen = Len(Text) newLen = curLength + incLen '' Will the new value fit in the remaining free space within the current buffer If newLen <= totalLength Then '' Buffer has room so just insert the new value Mid(buffer, curLength + 1, incLen) = Text Else '' Buffer does not have enough room so '' first calculate the new buffer size by doubling until its big enough '' then build the new buffer While totalLength < newLen totalLength = totalLength + totalLength Wend buffer = Left(buffer, curLength) & Text & Space(totalLength - newLen) End If curLength = newLen End Sub Public Property Get Length() As Integer Length = curLength End Property Public Property Get Text() As String Text = Left(buffer, curLength) End Property Public Sub Clear() totalLength = initialLength buffer = Space(totalLength) curLength = 0 End Sub

Y aquí hay un ejemplo sobre cómo usarlo:

Dim i As Long Dim sb As StringBuilder Dim result As String Set sb = New StringBuilder For i = 1 to 100000 sb.Append CStr( i) Next i result = sb.Text


No es una característica, pero una cosa que he visto tantas veces en VBA (y VB6): paréntesis agregado en llamadas a métodos donde cambiará la semántica:

Sub Foo() Dim str As String str = "Hello" Bar (str) Debug.Print str ''prints "Hello" because str is evaluated and a copy is passed Bar str ''or Call Bar(str) Debug.Print str ''prints "Hello World" End Sub Sub Bar(ByRef param As String) param = param + " World" End Sub


Posiblemente las características menos documentadas en VBA son aquellas que solo puede exponer al seleccionar "Mostrar miembros ocultos" en el navegador de objetos VBA. Los miembros ocultos son aquellas funciones que están en VBA, pero no son compatibles. Puede usarlos, pero Microsoft podría eliminarlos en cualquier momento. Ninguno de ellos tiene documentación provista, pero puede encontrar algunos en la web. Posiblemente, la característica más comentada de estas funciones ocultas proporcione acceso a punteros en VBA. Para un comentario decente, echa un vistazo; No tan ligero - Shlwapi.dll

Documentado, pero tal vez más oscuro (en cualquier caso, Excel) está utilizando ExecuteExcel4Macro para acceder a un espacio de nombres global oculto que pertenece a la instancia de la aplicación de Excel en lugar de un libro de trabajo específico.


Puede implementar interfaces con la palabra clave Implements .


Soporte para versiones localizadas, que (al menos en el siglo anterior) soportaban expresiones que usaban valores localizados. Como Pravda para True y FaƂszywy (no estoy seguro, pero al menos tenía la divertida L) para False en polaco ... En realidad, la versión en inglés podría leer macros en cualquier idioma y convertir sobre la marcha. Sin embargo, otras versiones localizadas no manejarían eso.

FALLAR.


VBA admite operadores bit a bit para comparar los dígitos binarios (bits) de dos valores. Por ejemplo, la expresión 4 y 7 evalúa los valores de bit de 4 (0100) y 7 (0111) y devuelve 4 (el bit que está activado en ambos números). De forma similar, la expresión 4 u 8 evalúa los valores de bit en 4 (0100 ) y 8 (1000) y devuelve 12 (1100), es decir, los bits donde cualquiera de ellos es verdadero.

Desafortunadamente, los operadores bit a bit tienen los mismos nombres en los operadores lógicos de comparación: E, Eqv, Imp, Not, Or y Xor. Esto puede generar ambigüedades e incluso resultados contradictorios.

Como ejemplo, abra la Ventana Inmediata (Ctrl + G) e ingrese:? (2 y 4) Esto devuelve cero, ya que no hay bits en común entre 2 (0010) y 4 (0100).


VBA en sí parece ser una característica oculta. Las personas que conozco que han usado productos de Office durante años no tienen idea de que son parte de la suite.

He publicado esto en varias preguntas aquí, pero el navegador de objetos es mi arma secreta. Si necesito código ninja algo muy rápido, pero no estoy familiarizado con el dll, Object Browser me salva la vida. Hace que sea mucho más fácil aprender las estructuras de clase que MSDN.

La ventana Locals es ideal para la depuración también. Ponga una pausa en su código y le mostrará todas las variables, sus nombres y sus valores y tipos actuales dentro del espacio de nombres actual.

¿Y quién podría olvidar a nuestro buen amigo Ventana Inmediata? No solo es excelente para la salida estándar de Debug.Print, sino que también puede ingresar comandos en ella. ¿Necesita saber qué es VariableX?

?VariableX

¿Necesitas saber de qué color es esa celda?

?Application.ActiveCell.Interior.Color

De hecho, todas esas ventanas son excelentes herramientas para ser productivo con VBA.


Declaraciones de deftype

Esta característica existe presumiblemente por compatibilidad con versiones anteriores. O para escribir un código de espagueti irremediablemente ofuscado. Tu selección.


IsDate("13.50") devuelve True pero IsDate("12.25.2010") devuelve False

Esto se debe a que IsDate podría IsDateTime mayor precisión IsDateTime . Y porque el período ( . ) Se trata como un separador de tiempo y no como un separador de fecha. Vea aquí para una explicación completa .


  • Guarde 4 pulsaciones de teclas enteras escribiendo debug.? xxx debug.? xxx lugar de debug.print xxx .
  • Crash it agregando: enum foo: me=0: end enum a la parte superior de un módulo que contiene cualquier otro código.