Vba Spanish

6/1/2021 Intitulado Página 1 VBA #vba https://translate.googleusercontent.com/translate_f 1/223 6/1/2021 Intitul

Views 123 Downloads 1 File size 5MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

6/1/2021

Intitulado

Página 1

VBA

#vba https://translate.googleusercontent.com/translate_f

1/223

6/1/2021

Intitulado

Página 2

Tabla de contenido Acerca de

1

Capítulo 1: Empezando con VBA

2

Observaciones

2

Versiones

2

Ejemplos

2

Accediendo al Editor de Visual Basic en Microsoft Office

2

Primer módulo y Hola mundo

4

Depuración

5

Ejecute el código paso a paso

5

Ventana de relojes

5

Ventana inmediata

5

Mejores prácticas de depuración

6

Capítulo 2: Llamadas a la API

7

Introducción

7

Observaciones

7

Ejemplos

8

Declaración y uso de API

8

API de Windows: módulo dedicado (1 de 2)

11

API de Windows: módulo dedicado (2 de 2)

15

API de Mac

19

Obtenga monitores totales y resolución de pantalla

20

FTP y API regionales

21

Capítulo 3: Matrices Ejemplos Declarar una matriz en VBA

25 25 25

Acceso a elementos

25

Indexación de matrices

25

Índice específico

25

Declaración dinámica

25

Uso de Split para crear una matriz a partir de una cadena

26

Iterando elementos de una matriz

27

Página 3

Para ... Siguiente

27

Para cada uno ... Siguiente

28

Matrices dinámicas (cambio de tamaño de matriz y manejo dinámico)

Matrices dinámicas

https://translate.googleusercontent.com/translate_f

29

29

2/223

6/1/2021

Intitulado Agregar valores dinámicamente

29

Eliminar valores dinámicamente

29

Restablecimiento de una matriz y reutilización dinámica

30

Matrices irregulares (matrices de matrices)

30

Matrices irregulares NO matrices multidimensionales

30

Crear una matriz irregular

31

Creación y lectura dinámica de matrices irregulares

31

Matrices multidimensionales

33

Matrices multidimensionales

33

Matriz de dos dimensiones

34

Matriz de tres dimensiones

36

Capítulo 4: Asignar cadenas con caracteres repetidos

40

Observaciones

40

Ejemplos

40

Utilice la función Cadena para asignar una cadena con n caracteres repetidos

40

Utilice las funciones String y Space para asignar una cadena de n caracteres

40

Capítulo 5: Atributos

41

Sintaxis

41

Ejemplos

41

VB_Name

41

VB_GlobalNameSpace

41

VB_Createable

41

VB_PredeclaredId

42

Declaración

42

Llamada

42

VB_Exposed

42

VB_Description

43

VB_ [Var] UserMemId

43

Página 4

Especificar el miembro predeterminado de una clase

43

Hacer una clase iterable con una construcción de bucle For Each

44

Capítulo 6: Automatización o uso de otras bibliotecas de aplicaciones

46

Introducción

46

Sintaxis

46

Observaciones

46

Ejemplos

46

Expresiones regulares de VBScript

Código

https://translate.googleusercontent.com/translate_f

46

47

3/223

6/1/2021

Intitulado Objeto de sistema de archivos de secuencias de comandos

48

Objeto Diccionario de secuencias de comandos

48

Objeto de Internet Explorer

49

Miembros básicos de Internet Explorer Objec

49

Raspado web

49

Hacer clic

51

Biblioteca de objetos HTML de Microsoft o Mejor amigo de IE

51

IE Principales problemas

52

Capítulo 7: Colecciones

53

Observaciones

53

Comparación de funciones con matrices y diccionarios

53

Ejemplos

53

Agregar elementos a una colección

53

Eliminar elementos de una colección

55

Obtener el recuento de elementos de una colección

56

Recuperar elementos de una colección

56

Determinar si existe una clave o un elemento en una colección

58

Llaves

58

Artículos

58

Borrar todos los elementos de una colección

Capítulo 8: Comentarios

59

61

Página 5 Observaciones

61

Ejemplos

61

Comentarios del apóstrofe

61

Comentarios REM

62

Capítulo 9: Concatenar cadenas

63

Observaciones

63

Ejemplos

63

Concatenar cadenas usando el operador &

63

Concatenar una matriz de cadenas usando la función Unir

63

Capítulo 10: Compilación condicional Ejemplos

64 64

Cambiar el comportamiento del código en tiempo de compilación

64

Uso de Declare Importaciones que funcionan en todas las versiones de Office

sesenta y cinco

Capítulo 11: Conversión de otros tipos a cadenas

67

Observaciones

67

Ejemplos

67

https://translate.googleusercontent.com/translate_f

4/223

6/1/2021

Intitulado Utilice CStr para convertir un tipo numérico en una cadena

67

Utilice Formato para convertir y formatear un tipo numérico como una cadena

67

Utilice StrConv para convertir una matriz de bytes de caracteres de un solo byte en una cadena

67

Convierta implícitamente una matriz de bytes de caracteres de varios bytes en una cadena

67

Capítulo 12: Copiar, devolver y pasar matrices Ejemplos Copiar matrices

69 69 69

Copiar matrices de objetos

70

Variantes que contienen una matriz

70

Devolución de matrices de funciones

Salida de una matriz a través de un argumento de salida

70

71

Salida a una matriz fija

71

Salida de una matriz desde un método de clase

72

Pasar matrices a procedimientos

Capítulo 13: CreateObject frente a GetObject

72

74

Página 6 Observaciones

74

Ejemplos

74

Demostrar GetObject y CreateObject

Capítulo 14: Creación de una clase personalizada

74

76

Observaciones

76

Ejemplos

76

Agregar una propiedad a una clase

76

Agregar funcionalidad a una clase

77

Alcance, instanciación y reutilización del módulo de clase

78

Capítulo 15: Creación de un procedimiento Ejemplos Introducción a los procedimientos

80 80 80

Devolviendo un valor

80

Función con ejemplos

81

Capítulo 16: Estructuras de datos

82

Introducción

82

Ejemplos

82

Lista enlazada

82

Árbol binario

83

Capítulo 17: Tipos de datos y límites

85

Ejemplos

85

Byte

85

https://translate.googleusercontent.com/translate_f

5/223

6/1/2021

Intitulado Entero

86

Booleano

86

Largo

87

Soltero

87

Doble

87

Moneda

88

Fecha

88

Cuerda

88

Longitud variable

89

Longitud fija

89

Página 7 Largo largo

89

Variante

90

LongPtr

91

Decimal

91

Capítulo 18: Manipulación de fecha y hora Ejemplos Calendario

Ejemplo Funciones base

93 93 93

93 94

Recuperar fecha y hora del sistema

94

Función de temporizador

94

IsDate ()

95

Funciones de extracción

Función DatePart () Funciones de cálculo

95

96 97

DateDiff ()

98

DateAdd ()

98

Conversión y creación

CDate () DateSerial ()

Capítulo 19: Declaración y asignación de cadenas

99

99 100

102

Observaciones

102

Ejemplos

102

Declarar una constante de cadena

102

Declarar una variable de cadena de ancho variable

102

Declarar y asignar una cadena de ancho fijo

102

Declarar y asignar una matriz de cadenas

102

Asignar caracteres específicos dentro de una cadena usando la declaración Mid

103

https://translate.googleusercontent.com/translate_f

6/223

6/1/2021

Intitulado Asignación hacia y desde una matriz de bytes

Capítulo 20: Declaración de variables Ejemplos

103

104 104

Declaración implícita y explícita

104

Variables

104

Página 8

Alcance

104

Variables locales

105

Variables estáticas

105

Campos

106

Campos de instancia

107

Encapsular campos

107

Constantes (Const)

108

Modificadores de acceso

109

Opción Módulo Privado

109

Sugerencias de tipo

Funciones integradas de retorno de cadenas

110

110

Declarar cadenas de longitud fija

112

Cuándo usar una variable estática

112

Capítulo 21: Manejo de errores

115

Ejemplos

115

Evitando condiciones de error

115

En declaración de error

116

Estrategias de manejo de errores

116

Línea de números

117

Reanudar palabra clave

En caso de error, reanudar siguiente Errores personalizados

118

118 120

Generando sus propios errores en tiempo de ejecución

120

Capítulo 22: Eventos

122

Sintaxis

122

Observaciones

122

Ejemplos

122

Fuentes y controladores

122

¿Qué son los eventos?

122

Manipuladores

122

https://translate.googleusercontent.com/translate_f

7/223

6/1/2021

Intitulado

Página 9 Fuentes Pasar datos a la fuente del evento

124 124

Usando parámetros pasados por referencia

124

Usando objetos mutables

125

Capítulo 23: Estructuras de control de flujo

127

Ejemplos

127

Seleccione el caso

127

Para cada bucle

128

Sintaxis

129

Hacer bucle

129

Mientras bucle

130

En bucle

130

Capítulo 24: Manipulación de cuerdas de uso frecuente

132

Introducción

132

Ejemplos

132

Manipulación de cadenas ejemplos de uso frecuente

Capítulo 25: Interfaces

132

134

Introducción

134

Ejemplos

134

Interfaz simple - Volable

134

Múltiples interfaces en una clase: se puede volar y se puede nadar

135

Capítulo 26: Seguridad de macros y firma de proyectos / módulos VBA Ejemplos Cree un certificado autofirmado digital válido SELFCERT.EXE

Capítulo 27: Medición de la longitud de cuerdas

138 138 138

151

Observaciones

151

Ejemplos

151

Use la función Len para determinar el número de caracteres en una cadena

151

Utilice la función LenB para determinar el número de bytes en una cadena

151

Prefiera `If Len (myString) = 0 Then` sobre` If myString = "" Then`

151

Capítulo 28: Convenciones de nomenclatura

152

Página 10 Ejemplos Nombres de variables

Notación húngara Nombres de procedimientos

https://translate.googleusercontent.com/translate_f

152 152

153 155

8/223

6/1/2021

Intitulado

Capítulo 29: Caracteres no latinos

157

Introducción

157

Ejemplos

157

Texto no latino en código VBA

157

Identificadores no latinos y cobertura de idiomas

158

Capítulo 30: VBA orientado a objetos Ejemplos

160 160

Abstracción

160

Los niveles de abstracción ayudan a determinar cuándo dividir las cosas.

160

Encapsulamiento

160

La encapsulación oculta los detalles de implementación del código del cliente.

160

Usar interfaces para imponer la inmutabilidad

161

Usando un método de fábrica para simular un constructor

163

Polimorfismo

164

El polimorfismo es la capacidad de presentar la misma interfaz para diferentes impleme subyacentes

164

El código comprobable depende de abstracciones

166

Capítulo 31: Operadores

167

Observaciones

167

Ejemplos

167

Operadores matemáticos

167

Operadores de concatenación

168

Operadores de comparación

169

Notas Operadores bit a bit \ lógicos

Capítulo 32: Pasando argumentos ByRef o ByVal

169 171

175

Introducción

175

Observaciones

175

Pasando matrices

175

Página 11 Ejemplos

175

Pasar variables simples ByRef y ByVal

175

ByRef

176

Modificador predeterminado Pasando por referencia

Forzar ByVal en el sitio de la llamada

176 177

177

ByVal

178

Pasando por valor

178

Capítulo 33: Llamadas a procedimientos Sintaxis

https://translate.googleusercontent.com/translate_f

180 180

9/223

6/1/2021

Intitulado Parámetros

180

Observaciones

180

Ejemplos

180

Sintaxis de llamada implícita

Caso extremo

180

180

Valores devueltos

181

Esto es confuso. ¿Por qué no usar siempre paréntesis?

181

Tiempo de ejecución

181

Tiempo de compilación

182

Sintaxis de llamada explícita

182

Argumentos opcionales

182

Capítulo 34: Lectura de archivos de 2GB + en binario en VBA y File Hashes

184

Introducción

184

Observaciones

184

MÉTODOS PARA LA CLASE DE MICROSOFT

184

PROPIEDADES DE LA CLASE POR MICROSOFT

185

MÓDULO NORMAL

185

Ejemplos

185

Esto tiene que estar en un módulo de clase, los ejemplos más adelante se denominarán "aleatorios"

185

Código para calcular el hash de archivo en un módulo estándar

189

Calcular todos los archivos hash desde una carpeta raíz

191

Pagina 12 Ejemplo de hoja de trabajo:

191

Código

191

Capítulo 35: Recurrencia

195

Introducción

195

Observaciones

195

Ejemplos

195

Factoriales

195

Recurrencia de carpeta

195

Capítulo 36: Scripting Objeto Diccionario

197

Observaciones

197

Ejemplos

197

Propiedades y métodos

197

Agregando datos con Scripting.Dictionary (Máximo, Recuento)

199

Obteniendo valores únicos con Scripting.

201

Capítulo 37: Scripting.FileSystemObject Ejemplos

https://translate.googleusercontent.com/translate_f

203 203

10/223

6/1/2021

Intitulado Creando un FileSystemObject

203

Leer un archivo de texto usando un FileSystemObject

203

Creando un archivo de texto con FileSystemObject

204

Escribir en un archivo existente con FileSystemObject

204

Enumerar archivos en un directorio usando FileSystemObject

204

Enumere carpetas y archivos de forma recursiva

205

Quitar la extensión de archivo de un nombre de archivo

206

Recuperar solo la extensión de un nombre de archivo

206

Recuperar solo la ruta de una ruta de archivo

207

Usando FSO.BuildPath para construir una ruta completa a partir de la ruta de la carpeta y el nombre del archivo

207

Capítulo 38: Búsqueda dentro de cadenas de la presencia de subcadenas

208

Observaciones

208

Ejemplos

208

Use InStr para determinar si una cadena contiene una subcadena

208

Use InStr para encontrar la posición de la primera instancia de una subcadena

208

Utilice InStrRev para encontrar la posición de la última instancia de una subcadena

208

Página 13 Capítulo 39: Clasificación

209

Introducción

209

Ejemplos

209

Implementación de algoritmos: clasificación rápida en una matriz unidimensional

209

Uso de la biblioteca de Excel para ordenar una matriz unidimensional

210

Capítulo 40: Literales de cadena: caracteres de escape, no imprimibles y continuaciones de línea

212

Observaciones

212

Ejemplos

212

Escapando del "personaje

212

Asignar literales de cadena larga

212

Usando constantes de cadena de VBA

213

Capítulo 41: Subcadenas

215

Observaciones

215

Ejemplos

215

Use Left o Left $ para obtener los 3 caracteres más a la izquierda en una cadena

215

Use Right o Right $ para obtener los 3 caracteres más a la derecha en una cadena

215

Use Mid o Mid $ para obtener caracteres específicos dentro de una cadena

215

Utilice Recortar para obtener una copia de la cadena sin espacios iniciales o finales

215

Capítulo 42: Formularios de usuario Ejemplos

217 217

Mejores prácticas

217

Trabaje con una nueva instancia cada vez.

217

https://translate.googleusercontent.com/translate_f

11/223

6/1/2021

Intitulado Implemente la lógica en otro lugar.

217

La persona que llama no debe preocuparse por los controles.

218

Maneja el evento QueryClose.

218

Escóndete, no cierres.

219

Nombra cosas.

219

Manejo de QueryClose

219

Un formulario de usuario cancelable

Capítulo 43: Palabra clave de opción de VBA

220

222

Sintaxis

222

Parámetros

222

Página 14 Observaciones

222

Ejemplos

223

Opción explícita

223

Opción Comparar {Binario | Texto | Base de datos}

223

Opción Comparar binario

223

Opción Comparar texto

224

Opción Comparar base de datos

225

Base de opciones {0 | 1}

225

Ejemplo en Base 0:

225

Mismo ejemplo con Base 1

226

El código correcto con Base 1 es:

226

Capítulo 44: Errores en tiempo de ejecución de VBA

228

Introducción

228

Ejemplos

228

Error en tiempo de ejecución '3': retorno sin GoSub

Código incorrecto ¿Por qué no funciona esto?

Código correcto ¿Por qué funciona esto?

Otras notas Error en tiempo de ejecución '6': desbordamiento

código incorrecto ¿Por qué no funciona esto?

Código correcto ¿Por qué funciona esto?

Otras notas Error en tiempo de ejecución '9': subíndice fuera de rango

https://translate.googleusercontent.com/translate_f

228

228 228

228 228

228 229

229 229

229 229

229 229

12/223

6/1/2021

Intitulado código incorrecto ¿Por qué no funciona esto?

Código correcto ¿Por qué funciona esto?

Otras notas

229 230

230 230

230

Página 15 Error en tiempo de ejecución '13': no coinciden los tipos

código incorrecto ¿Por qué no funciona esto?

Código correcto

230

230 231

231

¿Por qué funciona esto?

231

Error en tiempo de ejecución '91': variable de objeto o con variable de bloque no establecida

231

código incorrecto ¿Por qué no funciona esto?

Código correcto ¿Por qué funciona esto?

Otras notas Error en tiempo de ejecución '20': reanudar sin error

código incorrecto ¿Por qué no funciona esto?

Código correcto ¿Por qué funciona esto?

Otras notas

Capítulo 45: Trabajar con ADO

231 231

231 232

232 232

232 232

233 233

233

234

Observaciones

234

Ejemplos

234

Hacer una conexión a una fuente de datos

234

Recuperar registros con una consulta

235

Ejecutando funciones no escalares

236

Crear comandos parametrizados

237

Capítulo 46: Trabajar con archivos y directorios sin usar FileSystemObject

239

Observaciones

239

Ejemplos

239

Determinar si existen carpetas y archivos

239

Crear y eliminar carpetas de archivos

240

Créditos

https://translate.googleusercontent.com/translate_f

242

13/223

6/1/2021

Intitulado

Página 16

Acerca de Puede compartir este PDF con cualquier persona que crea que podría beneficiarse de él, descargue la última versión desde: vba Es un libro electrónico de VBA no oficial y gratuito creado con fines educativos. Se extrae todo el contenido desde Stack Overflow Documentation , que está escrita por muchas personas trabajadoras en Stack Desbordamiento. No está afiliado a Stack Overflow ni a VBA oficial. El contenido se publica bajo Creative Commons BY-SA, y la lista de contribuyentes de cada se proporcionan en la sección de créditos al final de este libro. Las imágenes pueden ser propiedad de sus respectivos dueños a menos que se especifique lo contrario. Todas las marcas comerciales y marcas comerciales registradas son propiedad de sus respectivos dueños de empresas. Utilice el contenido presentado en este libro bajo su propio riesgo; no se garantiza que sea correcto ni precisa, envíe sus comentarios y correcciones a [email protected]

https://riptutorial.com/

1

Página 17

Capítulo 1: Empezando con VBA Observaciones https://translate.googleusercontent.com/translate_f

14/223

6/1/2021

Intitulado

Esta sección proporciona una descripción general de qué es vba y por qué un desarrollador podría querer usarlo. También debe mencionar cualquier tema importante dentro de vba y vincular a los temas relacionados. Desde el La documentación para vba es nueva, es posible que deba crear versiones iniciales de esos temas relacionados.

Versiones Versión

Versiones de Office

Fecha de publicación Notas Fecha de publicación

Vba6

? - 2007

[Algún tiempo después] [1] 1992-06-30

Vba7

2010 - 2016

[blog.techkit.com] [2] 2010-04-15

VBA para Mac 2004, 2011-2016

2004-05-11

Ejemplos Accediendo al Editor de Visual Basic en Microsoft Office Puede abrir el editor VB en cualquiera de las aplicaciones de Microsoft Office presionando Alt + F11 o yendo a la pestaña Desarrollador y haciendo clic en el botón "Visual Basic". Si no ve la pestaña Desarrollador en la cinta, compruebe si está habilitado. De forma predeterminada, la pestaña Desarrollador está desactivada. Para habilitar la pestaña Desarrollador, vaya a Archivo -> Opciones, seleccione Personalice la cinta en la lista de la izquierda. En la vista de árbol "Personalizar la cinta" de la derecha, busque Elemento del árbol del desarrollador y marque la casilla de verificación de Desarrollador. Haga clic en Aceptar para cerrar el cuadro de diálogo Opciones.

https://riptutorial.com/

2

Página 18

https://translate.googleusercontent.com/translate_f

15/223

6/1/2021

Intitulado

La pestaña Desarrollador ahora está visible en la cinta en la que puede hacer clic en "Visual Basic" para abrir el Editor de Visual Basic. Alternativamente, puede hacer clic en "Ver código" para ver directamente el panel de código del elemento activo actualmente, por ejemplo, hoja de trabajo, gráfico, forma.

https://riptutorial.com/

3

Página 19

https://translate.googleusercontent.com/translate_f

16/223

6/1/2021

Intitulado

https://riptutorial.com/

4

Página 20 llave. ¡Felicidades! Ha creado su primer módulo VBA propio.

Depuración La depuración es una forma muy poderosa de observar más de cerca y corregir el funcionamiento incorrecto (o no código de trabajo).

Ejecute el código paso a paso Lo primero que debe hacer durante la depuración es detener el código en ubicaciones específicas y luego ejecutarlo línea por línea para ver si eso sucede lo que se espera. • Breakpoint ( F9 , Debug - Toggle breakpoint): puede agregar un punto de interrupción a cualquier línea ejecutada (por ejemplo, no a declaraciones), cuando la ejecución llega a ese punto, se detiene y da control a usuario. • También puede agregar la palabra clave Stop a una línea en blanco para que el código se detenga en esa ubicación en tiempo de ejecución. Esto es útil si, por ejemplo, antes de las líneas de declaración a las que no puede agregar una punto de interrupción con F9 • Step into ( F8 , Debug - Step into): ejecuta solo una línea de código, si es una llamada de un usuario sub / función definida, entonces se ejecuta línea por línea. • Pasar por encima ( Shift + F8 , Depurar - Pasar por encima): ejecuta una línea de código, no ingresa al usuario subs / funciones definidas. • Salir ( Ctrl + Shift + F8 , Depurar - Salir): Salir de la subfunción / función actual (ejecutar el código hasta fin). • Ejecutar al cursor ( Ctrl + F8 , Depurar - Ejecutar al cursor): ejecuta el código hasta llegar a la línea con el cursor. • Puede utilizar Debug.Print para imprimir líneas en la ventana Inmediato en tiempo de ejecución. También puede utilizar Debug.? como un atajo para Debug.Print

https://translate.googleusercontent.com/translate_f

17/223

6/1/2021

Intitulado

Ventana de relojes Ejecutar código línea por línea es solo el primer paso, necesitamos conocer más detalles y una herramienta para eso es la ventana de observación (Ver - Ventana de observación), aquí puede ver los valores de las expresiones definidas. A agregue una variable a la ventana de inspección, ya sea: • Haz clic derecho sobre él y luego selecciona "Agregar reloj". • Haga clic con el botón derecho en la ventana de inspección y seleccione "Agregar vigilancia". • Vaya a Depurar - Agregar reloj. Cuando agrega una nueva expresión, puede elegir si solo desea ver su valor o también romper la ejecución del código cuando es verdadero o cuando cambia su valor.

Ventana inmediata https://riptutorial.com/

5

Página 21 La ventana inmediata le permite ejecutar código arbitrario o imprimir elementos precediéndolos con la palabra clave Imprimir o un solo signo de interrogación " ? " Algunos ejemplos: • • • •

? ActiveSheet.Name :

devuelve el nombre de la hoja activa devuelve el nombre de la hoja activa ? foo - devuelve el valor de foo * x = 10 conjuntos x a 10 * Print ActiveSheet.Name :

* Obtener / configurar valores para variables a través de la ventana inmediata solo se puede realizar durante el tiempo de ejecución

Mejores prácticas de depuración Siempre que su código no funcione como se esperaba, lo primero que debe hacer es leerlo nuevamente con cuidado, buscando errores. Si eso no ayuda, comience a depurarlo; para procedimientos cortos, puede ser eficiente simplemente ejecutarlo línea por línea, para los más largos probablemente necesite establecer puntos de interrupción o interrupciones en la visualización expresiones, el objetivo aquí es encontrar la línea que no funciona como se esperaba. Una vez que tenga la línea que da el resultado incorrecto, pero la razón aún no está clara, intente simplificar expresiones, o reemplazar variables con constantes, que pueden ayudar a comprender si el valor de las variables es incorrecto. Si aún no puede resolverlo y pida ayuda: • Incluya la menor parte posible de su código para comprender su problema • Si el problema no está relacionado con el valor de las variables, reemplácelas por constantes. (entonces, en lugar de Hojas (a * b * c + d ^ 2) .Range (addressOfRange) escribe Hojas (4) .Range ("A2") ) • Describe qué línea da el comportamiento incorrecto y cuál es (error, resultado incorrecto ...) Lea Comenzando con VBA en línea: https://riptutorial.com/vba/topic/802/getting-started-with-vba

https://translate.googleusercontent.com/translate_f

18/223

6/1/2021

Intitulado

https://riptutorial.com/

6

Página 22

Capítulo 2: Llamadas a la API Introducción API significa Interfaz de programación de aplicaciones Las API para VBA implican un conjunto de métodos que permiten la interacción directa con el sistema operativo Las llamadas al sistema se pueden realizar ejecutando procedimientos definidos en archivos DLL

Observaciones Archivos de biblioteca de entornos operativos comunes (DLL): Enlace dinámico Biblioteca

Descripción

Advapi32.dll

Biblioteca de servicios avanzados para API que incluyen muchas funciones de seguridad y Llamadas de registro

Comdlg32.dll

Biblioteca de API de diálogo común

Gdi32.dll

Biblioteca de API de interfaz de dispositivo gráfico

Kernel32.dll

Compatibilidad con API base de Windows de 32 bits

Lz32.dll

Rutinas de compresión de 32 bits

Mpr.dll

Biblioteca de enrutadores de proveedores múltiples

Netapi32.dll

Biblioteca de API de red de 32 bits

Shell32.dll

Biblioteca de API de Shell de 32 bits

User32.dll

Biblioteca para rutinas de interfaz de usuario

Version.dll

Biblioteca de versiones

Winmm.dll

Biblioteca multimedia de Windows

Winspool.drv

Interfaz de cola de impresión que contiene las llamadas a la API de cola de impresión

Nuevos argumentos utilizados para el sistema 64: Tipo

Articulo

Descripción

Calificatorio

PtrSafe

Indica que la declaración Declare es compatible con 64 bits.

https://translate.googleusercontent.com/translate_f

19/223

6/1/2021

Intitulado

https://riptutorial.com/

7

Página 23 Tipo

Articulo

Descripción Este atributo es obligatorio en sistemas de 64 bits. Un tipo de datos variable que es un tipo de datos de 4 bytes en versiones de 32 bits y un tipo de datos de 8 bytes en las versiones de 64 bits de Office 2010. Esto es la forma recomendada de declarar un puntero o un identificador para nuevos

Tipo de datos

LongPtr

código sino también para el código heredado si tiene que ejecutarse en la versión de 64 bits de Office 2010. Solo se admite en el tiempo de ejecución de VBA 7 en 32 bits y 64 bits. Tenga en cuenta que puede asignarle valores numéricos pero no tipos numéricos Este es un tipo de datos de 8 bytes que solo está disponible en versiones de 64 bits

Tipo de datos

Largo largo

de Office 2010. Puede asignar valores numéricos pero no numéricos tipos (para evitar el truncamiento)

Operador de conversión CLngPtr Convierte una expresión simple en un tipo de datos LongPtr Operador de conversión CLngLng Convierte una expresión simple en un tipo de datos LongLong Función

VarPtr

Convertidor de variantes. Devuelve un LongPtr en versiones de 64 bits y un Largo en 32 bits (4 bytes)

Función

ObjPtr

Convertidor de objetos. Devuelve un LongPtr en versiones de 64 bits y un Long en 32 bits (4 bytes)

Función

StrPtr

Convertidor de cadenas. Devuelve un LongPtr en versiones de 64 bits y un Long en 32 bits (4 bytes)

Referencia completa de firmas de llamada: • Win32api32.txt para Visual Basic 5.0 (declaraciones de API antiguas, última revisión en marzo de 2005, Microsoft) • Win32API_PtrSafe con soporte de 64 bits (Office 2010, Microsoft)

Ejemplos Declaración y uso de API Declarar un procedimiento de DLL para trabajar con diferentes versiones de VBA: Opción explícita #Si Win64 Entonces Privado Declare PtrSafe Sub xLib "Kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long) #ElseIf Win32 Entonces Private Declare Sub apiSleep Lib "Kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)

https://riptutorial.com/

8

Página 24

#Terminara si

La declaración anterior le dice a VBA cómo llamar a la función "Sleep" definida en el archivo Kernel32.dll https://translate.googleusercontent.com/translate_f

20/223

6/1/2021

Intitulado

Win64 y Win32 son constantes predefinidas que se utilizan para compilación condicional

Constantes predefinidas Algunas constantes de compilación ya están predefinidas. Cuales existen dependerán del bitness de la versión de Office en la que está ejecutando VBA. Tenga en cuenta que Vba7 se introdujo junto con Office 2010 para admitir versiones de 64 bits de Office. Constante de 16 bits 32 bits 64 bits Vba6

Falso Si Vba6 Falso

Vba7

Falso si Vba7 es verdadero

Win16

Cierto

Win32

Falso verdadero

Cierto

Win64

Falso falso

Cierto

Mac

Falso si Mac

Si Mac

Falso

Falso

Estas constantes se refieren a la versión de Office, no a la versión de Windows. Por ejemplo Win32 = TRUE en Office de 32 bits, incluso si el sistema operativo es una versión de Windows de 64 bits. La principal diferencia al declarar API es entre las versiones de Office de 32 bits y 64 bits que introdujo nuevos tipos de parámetros (consulte la sección Comentarios para obtener más detalles)

Notas: • Las declaraciones se colocan en la parte superior del módulo y fuera de cualquier Subs o Funciones • Los procedimientos declarados en módulos estándar son públicos por defecto • Para declarar un procedimiento privado a un módulo, preceda la declaración con el Palabra clave privada • Los procedimientos DLL declarados en cualquier otro tipo de módulo son privados para ese módulo

Ejemplo simple para la llamada a la API de sueño: Pausa de prueba secundaria pública () Comienzo tenue como doble

https://riptutorial.com/

9

Página 25

start = temporizador Sleep 9000 'Pausa la ejecución durante 9 segundos Debug.Print "Paused for" & Format (Timer - start, "#, ###. 000") & "seconds" 'Resultado inmediato de la ventana: pausado durante 9.000 segundos End Sub

Se recomienda crear un módulo API dedicado para proporcionar un fácil acceso al sistema. funciones de envoltorios de VBA: subs o funciones de VBA normales que encapsulan los detalles necesarios para la llamada al sistema real, como los parámetros utilizados en las bibliotecas y la inicialización de esos https://translate.googleusercontent.com/translate_f

21/223

6/1/2021

Intitulado

parámetros El módulo puede contener todas las declaraciones y dependencias: • Firmas de métodos y estructuras de datos requeridas • Contenedores que realizan la validación de entrada y garantizan que todos los parámetros se pasen como se esperaba

Para declarar un procedimiento de DLL, agregue una instrucción Declare a la sección Declaraciones del código ventana. Si el procedimiento devuelve un valor, declárelo como una función : Declarar función publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [Como tipo] [, [ByVal] variable [Como tipo]] ...])] Como tipo

Si un procedimiento no devuelve un valor, declararlo como Sub : Declare Sub publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [As type] [, [ByVal] variable [Como tipo]] ...])]

• !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!! También es de destacar que la mayoría de las llamadas no válidas a las API bloquearán Excel y posiblemente archivos de datos corruptos • !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!

Office 2011 para Mac Sistema privado Declare Function Lib "libc.dylib" (comando ByVal como cadena) As Long Sub RunSafari () Resultado tenue tan largo resultado = sistema ("abrir -a Safari --args http://www.google.com") Debug.Print Str (resultado)

https://riptutorial.com/

10

Página 26

End Sub

Los ejemplos siguientes (API de Windows - Módulo dedicado (1 y 2)) muestran un módulo API que incluye declaraciones comunes para Win64 y Win32

API de Windows: módulo dedicado (1 de 2) Opción explícita #Si Win64, entonces 'Win64 = True, Win32 = False, Win16 = False Privada Declare PtrSafe Sub apiCopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (MyDest As Any, MySource como Any, ByVal MySize siempre que) Private Declare PtrSafe Sub apiSalirProcess Lib "Kernel32" Alias "ExitProcess" (ByVal uExitCode tan largo) Privado Declare PtrSafe Sub apiSetCursorPos Lib "User32" Alias "SetCursorPos" (ByVal X As Entero, ByVal Y como entero) Privada Declare PtrSafe Sub apiSleep Lib "Kernel32" Alias "Sleep" (ByVal dwMilliseconds As Largo) Función privada Declare PtrSafe apiAttachThreadInput Lib "User32" Alias "AttachThreadInput" (ByVal idAttach como largo, ByVal idAttachTo como largo, ByVal fAttach como largo) Tanto tiempo Función privada Declare PtrSafe apiBringWindowToTop Lib "User32" Alias "BringWindowToTop" (ByVal lngHWnd Tan largo) Tan largo Función privada Declare PtrSafe apiCloseWindow Lib "User32" Alias "CloseWindow" (ByVal hWnd As Long) Siempre que

https://translate.googleusercontent.com/translate_f

22/223

6/1/2021

Intitulado Función privada Declare PtrSafe apiDestroyWindow Lib "User32" Alias "DestroyWindow" (ByVal hWnd tan largo) como booleano Función privada Declare PtrSafe apiEndDialog Lib "User32" Alias "EndDialog" (ByVal hWnd As Long, ByVal result As Long) As Boolean Función privada Declare PtrSafe apiEnumChildWindows Lib "User32" Alias "EnumChildWindows" (ByVal hWndParent tan largo, ByVal pEnumProc tan largo, ByVal lParam tan largo) Función privada Declare PtrSafe apiSalirWindowsEx Lib "User32" Alias "ExitWindowsEx" (ByVal uFlags tan largo, ByVal dwReserved tan largo) Función privada Declare PtrSafe apiFindExecutable Lib "Shell32" Alias "FindExecutableA" (ByVal lpFile como cadena, ByVallpDirectory como cadena, ByVal lpResult como cadena) Tan largo Función privada Declare PtrSafe apiFindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName como cadena, ByVal lpWindowName como cadena) Tan largo Función privada Declare PtrSafe apiFindWindowEx Lib "User32" Alias "FindWindowExA" (ByVal hWnd1 tan largo, ByVal hWnd2 tan largo, ByVal lpsz1 como cadena, ByVal lpsz2 como cadena) Tan largo Función privada Declare PtrSafe apiGetActiveWindow Lib "User32" Alias "GetActiveWindow" () Siempre que Función privada Declare PtrSafe apiGetClassNameA Lib "User32" Alias "GetClassNameA" (ByVal hWnd tan largo, ByVal szClassName como cadena, ByVal lLength tan largo) Función privada Declare PtrSafe apiGetCommandLine Lib "Kernel32" Alias "GetCommandLineW" () Siempre que Función privada Declare PtrSafe apiGetCommandLineParams Lib "Kernel32" Alias "GetCommandLineA" () siempre que Función privada Declare PtrSafe apiGetDiskFreeSpaceEx Lib "Kernel32" Alias "GetDiskFreeSpaceExA" (ByVal lpDirectoryName como cadena, lpFreeBytesAvailableToCaller como Moneda, lpTotalNumberOfBytes como moneda, lpTotalNumberOfFreeBytes como moneda) As Long Función privada Declare PtrSafe apiGetDriveType Lib "Kernel32" Alias "GetDriveTypeA" (ByVal nDrive como cadena) Tan largo Función privada Declare PtrSafe apiGetSalirCodeProcess Lib "Kernel32" Alias "GetSalirCodeProcess" (ByVal hProcess tan largo, lpSalirCode tan largo) Función privada Declare PtrSafe apiGetForegroundWindow Lib "User32" Alias "GetForegroundWindow" () tan largo Función privada Declare PtrSafe apiGetFrequency Lib "Kernel32" Alias "QueryPerformanceFrequency" (cyFrequency como moneda) siempre que

https://riptutorial.com/

11

Página 27

Función privada Declare PtrSafe apiGetLastError Lib "Kernel32" Alias "GetLastError" () como Entero Función privada Declare PtrSafe apiGetParent Lib "User32" Alias "GetParent" (ByVal hWnd Siempre que) Función privada Declare PtrSafe apiGetSystemMetrics Lib "User32" Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long Función privada Declare PtrSafe apiGetSystemMetrics32 Lib "User32" Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long Función privada Declare PtrSafe apiGetTickCount Lib "Kernel32" Alias "QueryPerformanceCounter" (cyTickCount como moneda) siempre que Función privada Declare PtrSafe apiGetTickCountMs Lib "Kernel32" Alias "GetTickCount" () Tanto tiempo Función privada Declare PtrSafe apiGetUserName Lib "AdvApi32" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long Función privada Declare PtrSafe apiGetWindow Lib "User32" Alias "GetWindow" (ByVal hWnd Tan largo, ByVal wCmd Tan largo) Tan largo Función privada Declare PtrSafe apiGetWindowRect Lib "User32" Alias "GetWindowRect" (ByVal hWnd Tan largo, lpRect como winRect) Tan largo Función privada Declare PtrSafe apiGetWindowText Lib "User32" Alias "GetWindowTextA" (ByVal hWnd tan largo, ByVal szWindowText como cadena, ByVal lLength tan largo) Función privada Declare PtrSafe apiGetWindowThreadProcessId Lib "User32" Alias "GetWindowThreadProcessId" (ByVal hWnd tan largo, lpdwProcessId tan largo) Función privada Declare PtrSafe apiIsCharAlphaNumericA Lib "User32" Alias "IsCharAlphaNumericA" (ByVal byChar As Byte) Tan largo Función privada Declare PtrSafe apiIsIconic Lib "User32" Alias "IsIconic" (ByVal hWnd As Long) Tan largo Función privada Declare PtrSafe apiIsWindowVisible Lib "User32" Alias "IsWindowVisible" (ByVal hWnd As Long) Siempre que Función privada Declare PtrSafe apiIsZoomed Lib "User32" Alias "IsZoomed" (ByVal hWnd As Long) Tan largo Función privada Declare PtrSafe apiLStrCpynA Lib "Kernel32" Alias "lstrcpynA" (ByVal pDestination como cadena, ByVal pSource tan largo, ByVal iMaxLength como entero) Tan largo Función privada Declare PtrSafe apiMessageBox Lib "User32" Alias "MessageBoxA" (ByVal hWnd tan largo, ByVal lpText como cadena, ByVal lpCaption como cadena, ByVal wType tan largo) Función privada Declare PtrSafe apiOpenIcon Lib "User32" Alias "OpenIcon" (ByVal hWnd As Long) Tan largo Función privada Declare PtrSafe apiOpenProcess Lib "Kernel32" Alias "OpenProcess" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Función privada Declare PtrSafe apiPathAddBackslashByPointer Lib "ShlwApi" Alias "PathAddBackslashW" (ByVal lpszPath As Long) As Long

https://translate.googleusercontent.com/translate_f

23/223

6/1/2021

Intitulado Función privada Declare PtrSafe apiPathAddBackslashByString Lib "ShlwApi" Alias "PathAddBackslashW" (ByVal lpszPath como cadena) As Long 'http://msdn.microsoft.com/enus / library / aa155716% 28office.10% 29.aspx Función privada Declare PtrSafe apiPostMessage Lib "User32" Alias "PostMessageA" (ByVal hWnd tan largo, ByVal wMsg tan largo, ByVal wParam tan largo, ByVal lParam tan largo) Función privada Declare PtrSafe apiRegQueryValue Lib "AdvApi32" Alias "RegQueryValue" (ByVal hKey tan largo, ByVal sValueName como cadena, ByVal dwReserved tan largo, ByRef lValueType como Long, ByVal sValue As String, ByRef lResultLen As Long) As Long Función privada Declare PtrSafe apiSendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam Tan Long, lParam As Any) As Long Función privada Declare PtrSafe apiSetActiveWindow Lib "User32" Alias "SetActiveWindow" (ByVal hWnd As Long) Siempre que Función privada Declare PtrSafe apiSetCurrentDirectoryA Lib "Kernel32" Alias "SetCurrentDirectoryA" (ByVal lpPathName como cadena) Tan largo Función privada Declare PtrSafe apiSetFocus Lib "User32" Alias "SetFocus" (ByVal hWnd As Long) Tan largo Función privada Declare PtrSafe apiSetForegroundWindow Lib "User32" Alias "SetForegroundWindow" (ByVal hWnd As Long) As Long Función privada Declare PtrSafe apiSetLocalTime Lib "Kernel32" Alias "SetLocalTime" (lpSystem como SystemTime) Siempre que Función privada Declare PtrSafe apiSetWindowPlacement Lib "User32" Alias

https://riptutorial.com/

12

Página 28

"SetWindowPlacement" (ByVal hWnd As Long, ByRef lpwndpl As winPlacement) As Long Función privada Declare PtrSafe apiSetWindowPos Lib "User32" Alias "SetWindowPos" (ByVal hWnd As Long, ByVal hWndInsertAfter Tan Long, ByVal X As Long, ByVal Y Tan Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long Función privada Declare PtrSafe apiSetWindowText Lib "User32" Alias "SetWindowTextA" (ByVal hWnd tan largo, ByVal lpString como cadena) Tan largo Función privada Declare PtrSafe apiShellExecute Lib "Shell32" Alias "ShellExecuteA" (ByVal hWnd tan largo, ByVal lpOperation como cadena, ByVal lpFile como cadena, ByVal lpParameters Como cadena, ByVal lpDirectory como cadena, ByVal nShowCmd tan largo) Función privada Declare PtrSafe apiShowWindow Lib "User32" Alias "ShowWindow" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long Función privada Declare PtrSafe apiShowWindowAsync Lib "User32" Alias "ShowWindowAsync" (ByVal hWnd As Long, ByVal nCmdShow As Long) Tan largo Función privada Declare PtrSafe apiStrCpy Lib "Kernel32" Alias "lstrcpynA" (ByVal pDestination como cadena, ByVal pSource como cadena, ByVal iMaxLength como entero) As Long Función privada Declare PtrSafe apiStringLen Lib "Kernel32" Alias "lstrlenW" (ByVal lpString tan largo) tan largo Función privada Declare PtrSafe apiStrTrimW Lib "ShlwApi" Alias "StrTrimW" () como booleano Función privada Declare PtrSafe apiTerminateProcess Lib "Kernel32" Alias "TerminateProcess" (ByVal hWnd As Long, ByVal uSalirCode Tan Long) Función privada Declare PtrSafe apiTimeGetTime Lib "Winmm" Alias "timeGetTime" () As Long Función privada Declare PtrSafe apiVarPtrArray Lib "MsVbVm50" Alias "VarPtr" (Var () As Cualquiera) Siempre que Tipo privado browseInfo 'utilizado por apiBrowseForFolder hOwner As Long pidlRoot tan largo pszDisplayName como cadena lpszTitle como cadena ulFlags tan largo lpfn siempre que lParam tan largo iImage tan larga Tipo final Función privada Declare PtrSafe apiBrowseForFolder Lib "Shell32" Alias "SHBrowseForFolderA" (lpBrowseInfo como browseInfo) Tan largo Tipo privado CHOOSECOLOR 'utilizado por apiChooseColor; http://support.microsoft.com/kb/153929 y http://www.cpearson.com/Excel/Colors.aspx lStructSize siempre que hWndOwner siempre que hInstance tan largo rgbResult As Long lpCustColors como cadena banderas tan largas lCustData siempre que lpfnHook tan largo lpTemplateName como cadena Tipo final Función privada Declare PtrSafe apiChooseColor Lib "ComDlg32" Alias "ChooseColorA" (pElegir color como CHOOSECOLOR) Siempre que Estructura personalizada de FindWindowParameters de tipo privado para pasar los parámetros de entrada / salida de la función de enumeración de ganchos; podría usar variables globales en su lugar, pero esto es mejor

https://translate.googleusercontent.com/translate_f

24/223

6/1/2021

Intitulado strTitle As String 'INPUT hWnd tan largo

'SALIDA

Tipo final

'Encuentra una ventana específica con subtítulos dinámicos de un

lista de todas las ventanas abiertas: http://www.everythingaccess.com/tutorials.asp?ID=Bring-an-externalventana de la aplicación al primer plano Función privada Declare PtrSafe apiEnumWindows Lib "User32" Alias "EnumWindows" (ByVal lpEnumFunc As LongPtr, ByVal lParam As LongPtr) As Long Private Type lastInputInfo 'utilizado por apiGetLastInputInfo, getLastInputTime cbSize As Long dwTime As Long

https://riptutorial.com/

13

Página 29

Tipo final Función privada Declare PtrSafe apiGetLastInputInfo Lib "User32" Alias "GetLastInputInfo" (ByRef plii como lastInputInfo) Tan largo 'http://www.pgacon.com/visualbasic.htm#Take%20Advantage%20of%20Conditional%20Compilation 'Operadores lógicos y bit a bit en Visual Basic: http://msdn.microsoft.com/enus / library / wz3k228a (v = frente a 80) .aspx y http://stackoverflow.com/questions/1070863/hiddencaracterísticas-de-vba Tipo privado SystemTime wYear

Como entero

wMonth

Como entero

wDayOfWeek como entero wDía

Como entero

wHour

Como entero

wMinuto

Como entero

wSecond

Como entero

wMilliseconds como entero Tipo final Privada Declare PtrSafe Sub apiGetLocalTime Lib "Kernel32" Alias "GetLocalTime" (lpSystem Como SystemTime) Private Type pointAPI 'utilizado por apiSetWindowPlacement X tanto tiempo Y siempre que Tipo final Private Type rectAPI 'utilizado por apiSetWindowPlacement Left_Renamed As Long Top_Renamed As Long Right_Renamed As Long Bottom_Renamed As Long Tipo final WinPlacement de tipo privado 'utilizado por apiSetWindowPlacement longitud tan larga banderas tan largas showCmd tan largo ptMinPosition como pointAPI ptMaxPosition como pointAPI rcNormalPosition como rectAPI Tipo final Función privada Declare PtrSafe apiGetWindowPlacement Lib "User32" Alias "GetWindowPlacement" (ByVal hWnd As Long, ByRef lpwndpl As winPlacement) As Long Tipo privado winRect 'utilizado por apiMoveWindow Dejó tanto tiempo Arriba siempre que Tanto tiempo Fondo tan largo Tipo final Función privada Declare PtrSafe apiMoveWindow Lib "User32" Alias "MoveWindow" (ByVal hWnd Tan largo, xIzquierdo tan largo, ByVal yTop tan largo, wWidth tan largo, ByVal hHeight tan largo, ByVal repintar siempre que) Función privada Declare PtrSafe apiInternetOpen Lib "WiniNet" Alias "InternetOpenA" (ByVal sAgent como cadena, ByVal lAccessType tan largo, ByVal sProxyName como cadena, ByVal sProxyBypass As String, ByVal lFlags As Long) As Long 'Abrir el objeto de Internet' por ejemplo: lngINet = InternetOpen ("Control MyFTP", 1, vbNullString, vbNullString, 0) Función privada Declare PtrSafe apiInternetConnect Lib "WiniNet" Alias "InternetConnectA" (ByVal hInternetSession como largo, ByVal sServerName como cadena, ByVal nServerPort como entero, ByVal sUsername como cadena, ByVal sPassword como cadena, ByVal lService tan largo, ByVal lFlags como Long, ByVal lContext As Long) Siempre que 'Connect to the network' ex: lngINetConn = InternetConnect (lngINet, "ftp.microsoft.com", 0, "anónimo", "[email protected]", 1, 0, 0) Función privada Declare PtrSafe apiFtpGetFile Lib "WiniNet" Alias "FtpGetFileA" (ByVal hFtpSession como larga, ByVal lpszRemoteFile como cadena, ByVal lpszNewFile como cadena, ByVal fFailIfExists como booleano, ByVal dwFlagsAndAttributes como largo, ByVal dwFlags como largo, ByVal

https://translate.googleusercontent.com/translate_f

25/223

6/1/2021

Intitulado

https://riptutorial.com/

14

Página 30

dwContext tan largo) como booleano 'Obtener un archivo', por ejemplo: blnRC = FtpGetFile (lngINetConn, "dirmap.txt", "c: \ dirmap.txt", 0, 0, 1, 0) Función privada Declare PtrSafe apiFtpPutFile Lib "WiniNet" Alias "FtpPutFileA" (ByVal hFtpSession como larga, ByVal lpszLocalFile como cadena, ByVal lpszRemoteFile como cadena, ByVal dwFlags As Long, ByVal dwContext As Long) Como booleano 'Enviar un archivo' ej: blnRC = FtpPutFile (lngINetConn, "c: \ dirmap.txt", "dirmap.txt", 1, 0) Función privada Declare PtrSafe apiFtpDeleteFile Lib "WiniNet" Alias "FtpDeleteFileA" (ByVal hFtpSession tan largo, ByVal lpszFileName como cadena) Como booleano 'Eliminar un archivo' ex: blnRC = FtpDeleteFile (lngINetConn, "test.txt") Función privada Declare PtrSafe apiInternetCloseHandle Lib "WiniNet" (ByVal hInet As Long) Como entero 'Cerrar el objeto de Internet' ex: InternetCloseHandle lngINetConn 'ex: InternetCloseHandle lngINet Función privada Declare PtrSafe apiFtpFindFirstFile Lib "WiniNet" Alias "FtpFindFirstFileA" (ByVal hFtpSession tan largo, ByVal lpszSearchFile como cadena, lpFindFileData Como WIN32_FIND_DATA, ByVal dwFlags tan largo, ByVal dwContent tan largo) Tipo privado FILETIME dwLowDateTime tan largo dwHighDateTime tan largo Tipo final Tipo privado WIN32_FIND_DATA dwFileAttributes tan largo ftCreationTime como FILETIME ftLastAccessTime como FILETIME ftLastWriteTime como FILETIME nFileSizeHigh tan largo nFileSizeLow tanto tiempo dwReserved0 siempre que dwReserved1 siempre que cFileName como cadena * 1 'MAX_FTP_PATH cAlternate como cadena * 14 Tipo de finalización 'ex: lngHINet = FtpFindFirstFile (lngINetConn, "*. *", PData, 0, 0) Función privada Declare PtrSafe apiInternetFindNextFile Lib "WiniNet" Alias "InternetFindNextFileA" (ByVal hFind As Long, lpvFindData As WIN32_FIND_DATA) As Long 'ex: blnRC = InternetFindNextFile (lngHINet, pData) #ElseIf Win32 Then 'Win32 = True, Win16 = False

(continúa en el segundo ejemplo)

API de Windows: módulo dedicado (2 de 2) #ElseIf Win32 Then 'Win32 = True, Win16 = False Private Declare Sub apiCopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (MyDest As Any, MySource como cualquiera, ByVal MySize siempre que) Private Declare Sub apiExitProcess Lib "Kernel32" Alias "ExitProcess" (ByVal uSalirCode As Largo) 'Private Declare Sub apiGetStartupInfo Lib "Kernel32" Alias "GetStartupInfoA" (lpStartupInfo como STARTUPINFO) Private Declare Sub apiSetCursorPos Lib "User32" Alias "SetCursorPos" (ByVal X As Integer, ByVal Y As Integer) 'Operadores lógicos y bit a bit en Visual Basic: http://msdn.microsoft.com/en-us/library/wz3k228a(v=vs.80).aspx y http://stackoverflow.com/questions/1070863/hidden-features-of-vba 'http://www.pgacon.com/visualbasic.htm#Take%20Advantage%20of%20Conditional%20Compilation Private Declare Sub apiSleep Lib "Kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long) Función de declaración privada apiAttachThreadInput Lib "User32" Alias "AttachThreadInput" (ByVal idAttach tan largo, ByVal idAttachTo tan largo, ByVal fAttach tan largo) Función de declaración privada apiBringWindowToTop Lib "User32" Alias "BringWindowToTop" (ByVal lngHWnd tan largo) tan largo Función de declaración privada apiCloseHandle Lib "Kernel32" (ByVal hObject As Long) As Long Función de declaración privada apiCloseWindow Lib "User32" Alias "CloseWindow" (ByVal hWnd As

https://riptutorial.com/

15

Página 31

Long) Tan largo 'Función de declaración privada apiCreatePipe Lib "Kernel32" (phReadPipe As Long, phWritePipe As Long, lpPipeAttributes como SECURITY_ATTRIBUTES, ByVal nSize As Long) As Long 'Función de declaración privada apiCreateProcess Lib "Kernel32" Alias "CreateProcessA" (ByVal

https://translate.googleusercontent.com/translate_f

26/223

6/1/2021

Intitulado lpApplicationName tan largo, ByVal lpCommandLine como cadena, lpProcessAttributes como cualquiera, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment como cualquiera, ByVal lpCurrentDriectory como cadena, lpStartupInfo como STARTUPINFO, lpProcessInformation como PROCESS_INFORMATION) Siempre que Función de declaración privada apiDestroyWindow Lib "User32" Alias "DestroyWindow" (ByVal hWnd Tan largo) como booleano Función de declaración privada apiEndDialog Lib "User32" Alias "EndDialog" (ByVal hWnd As Long, ByVal result As Long) As Boolean Función de declaración privada apiEnumChildWindows Lib "User32" Alias "EnumChildWindows" (ByVal hWndParent tan largo, ByVal pEnumProc tan largo, ByVal lParam tan largo) Función de declaración privada apiSalirWindowsEx Lib "User32" Alias "ExitWindowsEx" (ByVal uFlags Siempre que, ByVal dwReservado Siempre que) Función de declaración privada apiFindExecutable Lib "Shell32" Alias "FindExecutableA" (ByVal lpFile como cadena, ByVallpDirectory como cadena, ByVal lpResult como cadena) Tan largo Función de declaración privada apiFindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName Como cadena, ByVal lpWindowName como cadena) tan largo Función de declaración privada apiFindWindowEx Lib "User32" Alias "FindWindowExA" (ByVal hWnd1 Tan largo, ByVal hWnd2 tan largo, ByVal lpsz1 como cadena, ByVal lpsz2 como cadena) Tan largo Función de declaración privada apiGetActiveWindow Lib "User32" Alias "GetActiveWindow" () como Largo Función de declaración privada apiGetClassNameA Lib "User32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal szClassName As String, ByVal lLength As Long) As Long Función de declaración privada apiGetCommandLine Lib "Kernel32" Alias "GetCommandLineW" () como Largo Función de declaración privada apiGetCommandLineParams Lib "Kernel32" Alias "GetCommandLineA" () Tanto tiempo Función de declaración privada apiGetDiskFreeSpaceEx Lib "Kernel32" Alias "GetDiskFreeSpaceExA" (ByVal lpDirectoryName como cadena, lpFreeBytesAvailableToCaller como moneda, lpTotalNumberOfBytes como moneda, lpTotalNumberOfFreeBytes como moneda) siempre que Función de declaración privada apiGetDriveType Lib "Kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) Tan largo Función de declaración privada apiGetSalirCodeProcess Lib "Kernel32" (ByVal hProcess As Long, lpSalirCode tan largo) Función de declaración privada apiGetFileSize Lib "Kernel32" (ByVal hFile As Long, lpFileSizeHigh siempre que) Función de declaración privada apiGetForegroundWindow Lib "User32" Alias "GetForegroundWindow" () Siempre que Función de declaración privada apiGetFrequency Lib "Kernel32" Alias "QueryPerformanceFrequency" (Cifrecuencia como moneda) Siempre que Función de declaración privada apiGetLastError Lib "Kernel32" Alias "GetLastError" () como entero Función de declaración privada apiGetParent Lib "User32" Alias "GetParent" (ByVal hWnd As Long) Tanto tiempo Función de declaración privada apiGetSystemMetrics Lib "User32" Alias "GetSystemMetrics" (ByVal nIndex As Long) Siempre que Función de declaración privada apiGetTickCount Lib "Kernel32" Alias "QueryPerformanceCounter" (cyTickCount como moneda) Siempre que Función de declaración privada apiGetTickCountMs Lib "Kernel32" Alias "GetTickCount" () As Long Función de declaración privada apiGetUserName Lib "AdvApi32" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long Función de declaración privada apiGetWindow Lib "User32" Alias "GetWindow" (ByVal hWnd As Long, ByVal wCmd As Long) Siempre que Función de declaración privada apiGetWindowRect Lib "User32" Alias "GetWindowRect" (ByVal hWnd Siempre que, lpRect como winRect) Siempre que Función de declaración privada apiGetWindowText Lib "User32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal szWindowText como cadena, ByVal lLength As Long) As Long Función de declaración privada apiGetWindowThreadProcessId Lib "User32" Alias "GetWindowThreadProcessId" (ByVal hWnd tan largo, lpdwProcessId tan largo)

https://riptutorial.com/

dieciséis

Página 32

Función de declaración privada apiIsCharAlphaNumericA Lib "User32" Alias "IsCharAlphaNumericA" (ByVal byChar As Byte) Siempre que Función de declaración privada apiIsIconic Lib "User32" Alias "IsIconic" (ByVal hWnd siempre que) Largo Función de declaración privada apiIsWindowVisible Lib "User32" Alias "IsWindowVisible" (ByVal hWnd As Long) Siempre que Función de declaración privada apiIsZoomed Lib "User32" Alias "IsZoomed" (ByVal hWnd siempre que) Largo Función de declaración privada apiLStrCpynA Lib "Kernel32" Alias "lstrcpynA" (ByVal pDestination Como cadena, ByVal pSource tan largo, ByVal iMaxLength como entero) Tan largo Función de declaración privada apiMessageBox Lib "User32" Alias "MessageBoxA" (ByVal hWnd As Long, ByVal lpText como cadena, ByVal lpCaption como cadena, ByVal wType tan largo) Función de declaración privada apiOpenIcon Lib "User32" Alias "OpenIcon" (ByVal hWnd siempre que) Largo Función de declaración privada apiOpenProcess Lib "Kernel32" Alias "OpenProcess" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long

https://translate.googleusercontent.com/translate_f

27/223

6/1/2021

Intitulado Función de declaración privada apiPathAddBackslashByPointer Lib "ShlwApi" Alias "PathAddBackslashW" (ByVal lpszPath As Long) As Long Función de declaración privada apiPathAddBackslashByString Lib "ShlwApi" Alias "PathAddBackslashW" (ByVal lpszPath como cadena) As Long 'http://msdn.microsoft.com/enus / library / aa155716% 28office.10% 29.aspx Función de declaración privada apiPostMessage Lib "User32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg tan largo, ByVal wParam tan largo, ByVal lParam tan largo) Función de declaración privada apiReadFile Lib "Kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long Función de declaración privada apiRegQueryValue Lib "AdvApi32" Alias "RegQueryValue" (ByVal hKey As Long, ByVal sValueName As String, ByVal dwReserved As Long, ByRef lValueType As Long, ByVal sValue As String, ByRef lResultLen As Long) As Long Función de declaración privada apiSendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg Tan largo, ByVal wParam Tan largo, lParam Como cualquiera) Tan largo Función de declaración privada apiSetActiveWindow Lib "User32" Alias "SetActiveWindow" (ByVal hWnd As Long) Siempre que Función de declaración privada apiSetCurrentDirectoryA Lib "Kernel32" Alias "SetCurrentDirectoryA" (ByVal lpPathName como cadena) Tan largo Función de declaración privada apiSetFocus Lib "User32" Alias "SetFocus" (ByVal hWnd As Long) Largo Función de declaración privada apiSetForegroundWindow Lib "User32" Alias "SetForegroundWindow" (ByVal hWnd As Long) Siempre que Función de declaración privada apiSetLocalTime Lib "Kernel32" Alias "SetLocalTime" (lpSystem As SystemTime) siempre que Función de declaración privada apiSetWindowPlacement Lib "User32" Alias "SetWindowPlacement" (ByVal hWnd As Long, ByRef lpwndpl As winPlacement) As Long Función de declaración privada apiSetWindowPos Lib "User32" Alias "SetWindowPos" (ByVal hWnd As Long, ByVal hWndInsertAfter tan largo, ByVal X tan largo, ByVal Y tan largo, ByVal cx tan largo, ByVal cy As Long, ByVal wFlags As Long) As Long Función de declaración privada apiSetWindowText Lib "User32" Alias "SetWindowTextA" (ByVal hWnd Tan largo, ByVal lpString como cadena) Tan largo Función de declaración privada apiShellExecute Lib "Shell32" Alias "ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation como cadena, ByVal lpFile como cadena, ByVal lpParameters como cadena, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long Función de declaración privada apiShowWindow Lib "User32" Alias "ShowWindow" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long Función de declaración privada apiShowWindowAsync Lib "User32" Alias "ShowWindowAsync" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long Función de declaración privada apiStrCpy Lib "Kernel32" Alias "lstrcpynA" (ByVal pDestination As String, ByVal pSource como cadena, ByVal iMaxLength como entero) Tan largo Función de declaración privada apiStringLen Lib "Kernel32" Alias "lstrlenW" (ByVal lpString As Long) Tan largo Función de declaración privada apiStrTrimW Lib "ShlwApi" Alias "StrTrimW" () como booleano Función de declaración privada apiTerminateProcess Lib "Kernel32" Alias "TerminateProcess" (ByVal hWnd tan largo, ByVal uSalirCode tan largo)

https://riptutorial.com/

17

Página 33

Función de declaración privada apiTimeGetTime Lib "Winmm" Alias "timeGetTime" () As Long Función de declaración privada apiVarPtrArray Lib "MsVbVm50" Alias "VarPtr" (Var () As Any) As Largo Función de declaración privada apiWaitForSingleObject Lib "Kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Tipo privado browseInfo 'utilizado por apiBrowseForFolder hOwner As Long pidlRoot tan largo pszDisplayName como cadena lpszTitle como cadena ulFlags tan largo lpfn siempre que lParam tan largo iImage tan larga Tipo final Función de declaración privada apiBrowseForFolder Lib "Shell32" Alias "SHBrowseForFolderA" (lpBrowseInfo como browseInfo) Tan largo Tipo privado CHOOSECOLOR 'utilizado por apiChooseColor; http://support.microsoft.com/kb/153929 y http://www.cpearson.com/Excel/Colors.aspx lStructSize siempre que hWndOwner siempre que hInstance tan largo rgbResult As Long lpCustColors como cadena banderas tan largas lCustData siempre que lpfnHook tan largo

https://translate.googleusercontent.com/translate_f

28/223

6/1/2021

Intitulado lpTemplateName como cadena Tipo final Función de declaración privada apiChooseColor Lib "ComDlg32" Alias "ChooseColorA" (pChoosecolor Como CHOOSECOLOR) siempre que Estructura personalizada de FindWindowParameters de tipo privado para pasar los parámetros de entrada / salida de la función de enumeración de ganchos; podría usar variables globales en su lugar, pero esto es mejor strTitle As String 'INPUT hWnd tan largo

'SALIDA

Tipo final

'Encuentra una ventana específica con subtítulos dinámicos de un

lista de todas las ventanas abiertas: http://www.everythingaccess.com/tutorials.asp?ID=Bring-an-externalventana de la aplicación al primer plano Función de declaración privada apiEnumWindows Lib "User32" Alias "EnumWindows" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long Private Type lastInputInfo 'utilizado por apiGetLastInputInfo, getLastInputTime cbSize As Long dwTime As Long Tipo final Función de declaración privada apiGetLastInputInfo Lib "User32" Alias "GetLastInputInfo" (ByRef plii As lastInputInfo) Tan largo Tipo privado SystemTime wYear

Como entero

wMonth

Como entero

wDayOfWeek como entero wDía

Como entero

wHour

Como entero

wMinuto

Como entero

wSecond

Como entero

wMilliseconds como entero Tipo final Private Declare Sub apiGetLocalTime Lib "Kernel32" Alias "GetLocalTime" (lpSystem As Hora del sistema) Punto de tipo privado API X tanto tiempo Y siempre que

https://riptutorial.com/

18

Página 34

Tipo final Tipo privado rectAPI Left_Renamed As Long Top_Renamed As Long Right_Renamed As Long Bottom_Renamed As Long Tipo final Tipo privado winPlacement longitud tan larga banderas tan largas showCmd tan largo ptMinPosition como pointAPI ptMaxPosition como pointAPI rcNormalPosition como rectAPI Tipo final Función de declaración privada apiGetWindowPlacement Lib "User32" Alias "GetWindowPlacement" (ByVal hWnd As Long, ByRef lpwndpl As winPlacement) As Long Tipo privado winRect Dejó tanto tiempo Arriba siempre que Tanto tiempo Fondo tan largo Tipo final Función de declaración privada apiMoveWindow Lib "User32" Alias "MoveWindow" (ByVal hWnd As Long, xLeft tan largo, ByVal yTop tan largo, wWidth tan largo, ByVal hHeight tan largo, ByVal repintado Siempre que) #Else 'Win16 = Verdadero #Terminara si

API de Mac Microsoft no admite oficialmente las API, pero con un poco de investigación se pueden encontrar más declaraciones en línea Office 2016 para Mac tiene espacio aislado https://translate.googleusercontent.com/translate_f

29/223

6/1/2021

Intitulado

A diferencia de otras versiones de las aplicaciones de Office que admiten VBA, las aplicaciones de Office 2016 para Mac son de espacio aislado. La zona de pruebas impide que las aplicaciones accedan a recursos fuera del contenedor de aplicaciones. Esto afecta cualquier complemento o macros que implique el acceso a archivos o la comunicación entre procesos. Usted puede Minimice los efectos del sandboxing utilizando los nuevos comandos descritos en la siguiente sección. Nuevos comandos de VBA para Office 2016 para Mac Los siguientes comandos de VBA son nuevos y exclusivos de Office 2016 para Mac. Mando

Utilizar para

GrantAccessToMultipleFiles Solicita el permiso de un usuario para acceder a varios archivos a la vez AppleScriptTask

Llamar a scripts externos de AppleScript desde VB

MAC_OFFICE_VERSION

IFDEF entre diferentes versiones de Mac Office en tiempo de compilación

Office 2011 para Mac https://riptutorial.com/

19

Página 35

Sistema privado Declare Function Lib "libc.dylib" (comando ByVal como cadena) As Long Función de declaración privada popen Lib "libc.dylib" (comando ByVal como cadena, modo ByVal como String) tan largo Función de declaración privada pclose Lib "libc.dylib" (archivo ByVal siempre que sea largo) Función de declaración privada fread Lib "libc.dylib" (ByVal outStr As String, ByVal size As Long, Elementos ByVal As Long, ByVal stream As Long) As Long Función de declaración privada feof Lib "libc.dylib" (archivo ByVal siempre que sea largo)



Office 2016 para Mac Función privada Declare PtrSafe popen Lib "libc.dylib" (comando ByVal como cadena, modo ByVal Como cadena) Como LongPtr Función privada Declare PtrSafe pclose Lib "libc.dylib" (archivo ByVal como LongPtr) As Long Función privada Declare PtrSafe fread Lib "libc.dylib" (ByVal outStr As String, ByVal size As Elementos LongPtr, ByVal As LongPtr, ByVal stream As LongPtr) As Long Función privada Declare PtrSafe feof Lib "libc.dylib" (archivo ByVal como LongPtr) como LongPtr

Obtenga monitores totales y resolución de pantalla Opción explícita Información de GetSystemMetrics32: http://msdn.microsoft.com/en-us/library/ms724385(VS.85).aspx #Si Win64 Entonces Función privada Declare PtrSafe GetSystemMetrics32 Lib "User32" Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long #ElseIf Win32 Entonces Función de declaración privada GetSystemMetrics32 Lib "User32" Alias "GetSystemMetrics" (ByVal nIndex As Long) Siempre que #Terminara si 'Envoltorios de VBA: Función pública dllGetMonitors () tan largo Const SM_CMONITORS = 80 dllGetMonitors = GetSystemMetrics32 (SM_CMONITORS) Función final Función pública dllGetHorizontalResolution () As Long Const SM_CXVIRTUALSCREEN = 78 dllGetHorizontalResolution = GetSystemMetrics32 (SM_CXVIRTUALSCREEN) Función final Función pública dllGetVerticalResolution () As Long Const SM_CYVIRTUALSCREEN = 79 dllGetVerticalResolution = GetSystemMetrics32 (SM_CYVIRTUALSCREEN)

https://translate.googleusercontent.com/translate_f

30/223

6/1/2021

Intitulado Función final Public Sub ShowDisplayInfo () Debug.Print "Monitores totales:" & vbTab & vbTab & dllGetMonitors Debug.Print "Resolución horizontal:" & vbTab & dllGetHorizontalResolution Debug.Print "Resolución vertical:" & vbTab & dllGetVerticalResolution 'Monitores totales:

1

'Resolución horizontal: 1920 'Resolución vertical: 1080 End Sub

https://riptutorial.com/

20

Página 36

FTP y API regionales modFTP Opción explícita Opción Comparar texto Opción Módulo Privado 'http://msdn.microsoft.com/en-us/library/aa384180(v=VS.85).aspx 'http://www.dailydoseofexcel.com/archives/2006/01/29/ftp-via-vba/ 'http://www.15seconds.com/issue/981203.htm 'Abra el objeto de Internet Función de declaración privada InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (_ ByVal sAgent como cadena, _ ByVal lAccessType As Long, _ ByVal sProxyName como cadena, _ ByVal sProxyBypass como cadena, _ ByVal lFlags As Long _ ) Tanto tiempo 'ex: lngINet = InternetOpen ("Control MyFTP", 1, vbNullString, vbNullString, 0) 'Conéctese a la red Función de declaración privada InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (_ ByVal hInternetSession siempre que, _ ByVal sServerName como cadena, _ ByVal nServerPort como entero, _ ByVal sUsername como cadena, _ ByVal sPassword como cadena, _ ByVal lService siempre que, _ ByVal lFlags As Long, _ ByVal lContext tan largo _ ) Tanto tiempo 'ej: lngINetConn = InternetConnect (lngINet, "ftp.microsoft.com", 0, "anónimo", "[email protected]", 1, 0, 0) 'Obtener un archivo Función de declaración privada FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" (_ ByVal hFtpSession siempre que, _ ByVal lpszRemoteFile como cadena, _ ByVal lpszNewFile como cadena, _ ByVal fFailIfExists como booleano, _ ByVal dwFlagsAndAttributes As Long, _ ByVal dwFlags As Long, _ ByVal dwContext siempre que _ ) Como booleano 'ex: blnRC = FtpGetFile (lngINetConn, "dirmap.txt", "c: \ dirmap.txt", 0, 0, 1, 0) 'Enviar un archivo Función de declaración privada FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" _ (_ ByVal hFtpSession siempre que, _ ByVal lpszLocalFile como cadena, _ ByVal lpszRemoteFile como cadena, _ ByVal dwFlags tan largo, ByVal dwContext tan largo _ ) Como booleano 'ex: blnRC = FtpPutFile (lngINetConn, "c: \ dirmap.txt", "dirmap.txt", 1, 0) 'Eliminar un archivo Función de declaración privada FtpDeleteFile Lib "wininet.dll" Alias "FtpDeleteFileA" _

https://translate.googleusercontent.com/translate_f

31/223

6/1/2021

Intitulado

https://riptutorial.com/

21

Página 37

(_ ByVal hFtpSession siempre que, _ ByVal lpszFileName como cadena _ ) Como booleano 'ex: blnRC = FtpDeleteFile (lngINetConn, "test.txt") 'Cerrar el objeto de Internet Función de declaración privada InternetCloseHandle Lib "wininet.dll" (ByVal hInet siempre que) Entero por ejemplo: InternetCloseHandle lngINetConn por ejemplo: InternetCloseHandle lngINet

Función de declaración privada FtpFindFirstFile Lib "wininet.dll" Alias "FtpFindFirstFileA" _ (_ ByVal hFtpSession siempre que, _ ByVal lpszSearchFile como cadena, _ lpFindFileData como WIN32_FIND_DATA, _ ByVal dwFlags As Long, _ ByVal dwContent tan largo _ ) Tanto tiempo Tipo privado FILETIME dwLowDateTime tan largo dwHighDateTime tan largo Tipo final Tipo privado WIN32_FIND_DATA dwFileAttributes tan largo ftCreationTime como FILETIME ftLastAccessTime como FILETIME ftLastWriteTime como FILETIME nFileSizeHigh tan largo nFileSizeLow tanto tiempo dwReserved0 siempre que dwReserved1 siempre que cFileName como cadena * MAX_FTP_PATH cAlternate como cadena * 14 Tipo final 'por ejemplo: lngHINet = FtpFindFirstFile (lngINetConn, "*. *", pData, 0, 0) Función de declaración privada InternetFindNextFile Lib "wininet.dll" Alias "InternetFindNextFileA" _ (_ ByVal hFind As Long, _ lpvFindData como WIN32_FIND_DATA _ ) Tanto tiempo 'por ejemplo: blnRC = InternetFindNextFile (lngHINet, pData)

Public Sub showLatestFTPVersion () Dim ftpSuccess como booleano, msg como cadena, lngFindFirst como largo Dim lngINet tan largo, lngINetConn tan largo Atenuar pData como WIN32_FIND_DATA 'init el búfer de nombre de archivo pData.cFileName = Cadena (260, 0) msg = "Error de FTP" lngINet = InternetOpen ("Control MyFTP", 1, vbNullString, vbNullString, 0) Si lngINet> 0 entonces lngINetConn = InternetConnect (lngINet, FTP_SERVER_NAME, FTP_SERVER_PORT, FTP_USER_NAME, FTP_PASSWORD, 1, 0, 0)

https://riptutorial.com/

22

Página 38

Si lngINetConn> 0, entonces FtpPutFile lngINetConn, "C: \ Tmp \ ftp.cls", "ftp.cls", FTP_TRANSFER_BINARY, 0 'lngFindFirst = FtpFindFirstFile (lngINetConn, "ExcelDiff.xlsm", pData, 0, 0)

https://translate.googleusercontent.com/translate_f

32/223

6/1/2021

Intitulado Si lngINet = 0 entonces msg = "Error de DLL:" & Err.LastDllError & ", Número de error:" & Err.Number & ", Error Desc: "& Err.Description Más msg = left (pData.cFileName, InStr (1, pData.cFileName, String (1, 0), vbBinaryCompare) - 1) Terminara si InternetCloseHandle lngINetConn Terminara si InternetCloseHandle lngINet Terminara si MsgBox msg End Sub

modRegional: Opción explícita Const privada LOCALE_SDECIMAL = & HE Const privada LOCALE_SLIST = & HC Función de declaración privada GetLocaleInfo Lib "Kernel32" Alias "GetLocaleInfoA" (ByVal Locale As Long, ByVal LCType tan largo, ByVal lpLCData como cadena, ByVal cchData tan largo) Función de declaración privada SetLocaleInfo Lib "Kernel32" Alias "SetLocaleInfoA" (ByVal Locale As Long, ByVal LCType tan largo, ByVal lpLCData como cadena) como booleano Función de declaración privada GetUserDefaultLCID% Lib "Kernel32" () Función pública getTimeSeparator () como cadena getTimeSeparator = Application.International (xlTimeSeparator) Función final Función pública getDateSeparator () como cadena getDateSeparator = Application.International (xlDateSeparator) Función final Función pública getListSeparator () como cadena Dim ListSeparator como cadena, iRetVal1 tan largo, iRetVal2 tan largo, lpLCDataVar como cadena, Posición como entero, configuración regional tan larga Locale = GetUserDefaultLCID () iRetVal1 = GetLocaleInfo (Locale, LOCALE_SLIST, lpLCDataVar, 0) ListSeparator = String $ (iRetVal1, 0) iRetVal2 = GetLocaleInfo (Locale, LOCALE_SLIST, ListSeparator, iRetVal1) Posición = InStr (ListSeparator, Chr $ (0)) Si Posición> 0, entonces ListSeparator = Left $ (ListSeparator, Position - 1) Else ListSeparator = vbNullString getListSeparator = ListSeparator Función final Private Sub ChangeSettingExample () 'cambia la configuración del carácter mostrado como separador decimal. Llame a SetLocalSetting (LOCALE_SDECIMAL, ",") 'para cambiar a "," Detener

'revise su panel de control para verificar o usar el

Función API GetLocaleInfo Llame a SetLocalSetting (LOCALE_SDECIMAL, ".") 'Para volver a cambiar a "." End Sub Función privada SetLocalSetting (LC_CONST tan largo, configuración como cadena) como booleano Llamar a SetLocaleInfo (GetUserDefaultLCID (), LC_CONST, Configuración)

https://riptutorial.com/

23

Página 39

Función final

Leer API Calls en línea: https://riptutorial.com/vba/topic/10569/api-calls

https://translate.googleusercontent.com/translate_f

33/223

6/1/2021

Intitulado

https://riptutorial.com/

24

Página 40

Capítulo 3: Matrices Ejemplos Declarar una matriz en VBA Declarar una matriz es muy similar a declarar una variable, excepto que debe declarar la dimensión de la matriz justo después de su nombre: Dim myArray (9) As String 'Declarando una matriz que contendrá hasta 10 cadenas

De forma predeterminada, las matrices en VBA están indexadas desde CERO , por lo tanto, el número dentro del paréntesis no se refiere al tamaño de la matriz, sino al índice del último elemento

Acceso a elementos El acceso a un elemento de la matriz se realiza mediante el nombre de la matriz, seguido del índice https://translate.googleusercontent.com/translate_f

34/223

6/1/2021

Intitulado

del elemento, entre paréntesis: myArray (0) = "primer elemento" myArray (5) = "sexto elemento" myArray (9) = "último elemento"

Indexación de matrices Puede cambiar la indexación de matrices colocando esta línea en la parte superior de un módulo: Opción Base 1

Con esta línea, todas las matrices declaradas en el módulo se indexarán desde ONE .

Índice específico También puede declarar cada Array con su propio índice utilizando la palabra clave To , y la menor y límite superior (= índice): Dim mySecondArray (1 To 12) As String 'Matriz de 12 cadenas indexadas de 1 a 12 Dim myThirdArray (13 To 24) As String 'Array de 12 cadenas indexadas de 13 a 24

Declaración dinámica Cuando no conoce el tamaño de su Array antes de su declaración, puede usar la dinámica declaración y la palabra clave ReDim :

https://riptutorial.com/

25

Página 41

Dim myDynamicArray () As Strings 'Crea una matriz de un número desconocido de cadenas ReDim myDynamicArray (5) 'Esto restablece la matriz a 6 elementos

Tenga en cuenta que el uso de la palabra clave ReDim eliminará cualquier contenido anterior de su matriz. Para prevenir esto, puede usar la palabra clave Preserve después de ReDim : Dim myDynamicArray (5) como cadena myDynamicArray (0) = "Algo que quiero conservar" ReDim Preserve myDynamicArray (8) 'Expande el tamaño hasta 9 cadenas Debug.Print myDynamicArray (0) 'todavía imprime el elemento

Uso de Split para crear una matriz a partir de una cadena Función dividida devuelve una matriz unidimensional de base cero que contiene un número específico de subcadenas. Sintaxis Dividir (expresión [, delimitador [, límite [, comparar ]]] ) Parte

Descripción Necesario. Expresión de cadena que contiene subcadenas y delimitadores. Si expresión

expresión

es una cadena de longitud cero ("" o vbNullString), Split devuelve una matriz vacía que no contiene elementos ni datos. En este caso, la matriz devuelta tendrá un LBound de 0 y UBound de -1. Opcional. Carácter de cadena utilizado para identificar límites de subcadena. Si se omite, el espacio

https://translate.googleusercontent.com/translate_f

35/223

6/1/2021

Intitulado

delimitador

Se supone que el carácter ("") es el delimitador. Si el delimitador es de longitud cero cadena, una matriz de un solo elemento que contiene la cadena de expresión completa es regresó. Opcional. Número de subcadenas que se devolverán; -1 indica que todas las subcadenas se devuelven.

límite

comparar

Opcional. Valor numérico que indica el tipo de comparación que se utilizará cuando evaluar subcadenas. Consulte la sección Configuración para conocer los valores.

Configuraciones El argumento de comparación puede tener los siguientes valores: Constante

Descripción del valor

Descripción

-1

Realiza una comparación usando la configuración de la Opción Compare declaración.

https://riptutorial.com/

26

Página 42 Constante

Descripción del valor

vbBinaryCompare

0

Realiza una comparación binaria.

vbTextCompare

1

Realiza una comparación textual.

vbDatabaseCompare 2

Solo Microsoft Access. Realiza una comparación basada en información en su base de datos.

Ejemplo En este ejemplo se demuestra cómo funciona Split mostrando varios estilos. Los comentarios muestra el conjunto de resultados para cada una de las diferentes opciones de división realizadas. Finalmente se demuestra como para recorrer la matriz de cadenas devuelta. Subprueba Dim textArray () como cadena textArray = Split ("Tecnología en la red") 'Resultado: {"Tech", "on", "the", "Net"} textArray = Dividir ("172.23.56.4", ".") 'Resultado: {"172", "23", "56", "4"} textArray = Dividir ("A; B; C; D", ";") 'Resultado: {"A", "B", "C", "D"} textArray = Dividir ("A; B; C; D", ";", 1) 'Resultado: {"A; B; C; D"} textArray = Dividir ("A; B; C; D", ";", 2) 'Resultado: {"A", "B; C; D"} textArray = Dividir ("A; B; C; D", ";", 3) 'Resultado: {"A", "B", "C; D"} textArray = Dividir ("A; B; C; D", ";", 4) 'Resultado: {"A", "B", "C", "D"} 'Puede iterar sobre la matriz creada Contador de atenuación siempre que Para contador = LBound (textArray) a UBound (textArray) Debug.Print textArray (contador)

https://translate.googleusercontent.com/translate_f

36/223

6/1/2021

Intitulado próximo End Sub

Iterando elementos de una matriz

Para ... Siguiente El uso de la variable de iterador como número de índice es la forma más rápida de iterar los elementos de un formación:

https://riptutorial.com/

27

Página 43

Atenuar elementos como variante elementos = Matriz (0, 1, 2, 3) Dim index como entero Para index = LBound (elementos) a UBound (elementos) 'asume que el valor se puede convertir implícitamente en una cadena: Debug.Print elementos (índice) próximo

Los bucles anidados se pueden utilizar para iterar matrices multidimensionales: Atenuar elementos (0 a 1, 0 a 1) como entero elementos (0, 0) = 0 elementos (0, 1) = 1 elementos (1, 0) = 2 elementos (1, 1) = 3 Atenuar exterior como entero Dim interior como entero Para exterior = LBound (elementos, 1) A UBound (elementos, 1) Para inner = LBound (elementos, 2) A UBound (elementos, 2) 'asume que el valor se puede convertir implícitamente en una cadena: Debug.Print elementos (exterior, interior) próximo próximo

Para cada uno ... Siguiente Un bucle For Each ... Next también se puede utilizar para iterar matrices, si el rendimiento no importa: Atenuar elementos como variante elementos = Matriz (0, 1, 2, 3) Atenuar el elemento como variante 'debe ser una variante Para cada artículo en artículos 'asume que el valor se puede convertir implícitamente en una cadena: Debug.Print elemento próximo

Un bucle For Each iterará todas las dimensiones de exterior a interior (el mismo orden en que se muestran los elementos establecidos en la memoria), por lo que no hay necesidad de bucles anidados: Atenuar elementos (0 a 1, 0 a 1) como entero elementos (0, 0) = 0 elementos (1, 0) = 1 elementos (0, 1) = 2 elementos (1, 1) = 3 Atenuar elemento como variante 'debe ser variante Para cada artículo en artículos 'asume que el valor se puede convertir implícitamente en una cadena: Debug.Print elemento próximo

https://translate.googleusercontent.com/translate_f

37/223

6/1/2021

Intitulado

https://riptutorial.com/

28

Página 44 Tenga en cuenta que los bucles For Each se utilizan mejor para iterar objetos de colección , si el rendimiento es importante.

Los 4 fragmentos anteriores producen el mismo resultado: 0 1 2 3

Matrices dinámicas (cambio de tamaño de matriz y manejo dinámico)

Matrices dinámicas Agregar y reducir variables en una matriz de forma dinámica es una gran ventaja para cuando la información que está tratando no tiene un número determinado de variables.

Agregar valores dinámicamente Simplemente puede cambiar el tamaño de la matriz con la declaración ReDim , esto cambiará el tamaño de la matriz, pero si cuál para retener la información ya almacenada en la matriz necesitará la parte Preserve . En el siguiente ejemplo, creamos una matriz y la aumentamos en una variable más en cada iteración. conservando los valores que ya están en la matriz. Dim Dynamic_array como variante 'primero establecemos Dynamic_array como variante Para n = 1 a 100 Si está vacío (matriz_dinámica), entonces 'isempty () verificará si necesitamos agregar el primer valor a la matriz o el siguiente unos ReDim Dynamic_array (0) 'ReDim Dynamic_array (0) cambiará el tamaño de la matriz a una sola variable Matriz_dinámica (0) = n Más ReDim Preserve Dynamic_array (0 a UBound (Dynamic_array) + 1) 'en la línea de arriba cambiamos el tamaño de la matriz de la variable 0 al UBound () = last variable, más uno que aumenta efectivamente el tamaño de la matriz en uno Matriz_dinámica (UBound (Matriz_dinámica)) = n 'atribuir un valor a la última variable de Dynamic_array Terminara si próximo

Eliminar valores dinámicamente Podemos utilizar la misma lógica para disminuir la matriz. En el ejemplo, el valor "último" será

https://riptutorial.com/

29

Página 45 eliminado de la matriz. https://translate.googleusercontent.com/translate_f

38/223

6/1/2021

Intitulado Dim Dynamic_array como variante Dynamic_array = Array ("primero", "medio", "último") ReDim Preserve Dynamic_array (0 a UBound (Dynamic_array) - 1) 'Cambiar el tamaño de la reserva mientras se suelta el último valor

Restablecimiento de una matriz y reutilización dinámica También podemos reutilizar las matrices que creamos para no tener muchas en la memoria, lo que haría el tiempo de ejecución más lento. Esto es útil para matrices de varios tamaños. Un fragmento que podría utilizar para volver utilizar la matriz es ReDim la matriz de nuevo a (0) , atribuir una variable a la matriz y libremente aumente la matriz de nuevo. En el fragmento de abajo, construyo una matriz con los valores de 1 a 40, vacío la matriz y vuelvo a llenar el matriz con valores de 40 a 100, todo esto realizado de forma dinámica. Dim Dynamic_array como variante Para n = 1 a 100 Si está vacío (matriz_dinámica), entonces ReDim Dynamic_array (0) Matriz_dinámica (0) = n ElseIf Dynamic_array (0) = "" Entonces 'si la primera variante está vacía (= "") entonces dale el valor de n Matriz_dinámica (0) = n Más ReDim Preserve Dynamic_array (0 a UBound (Dynamic_array) + 1) Matriz_dinámica (UBound (Matriz_dinámica)) = n Terminara si Si n = 40 Entonces ReDim Dynamic_array (0) 'Cambiar el tamaño de la matriz a una variable sin preservar, 'dejando el primer valor de la matriz vacío Terminara si próximo

Matrices irregulares (matrices de matrices)

Matrices irregulares NO matrices multidimensionales Las matrices de matrices (matrices irregulares) no son lo mismo que matrices multidimensionales si piensa en ellos visualmente las matrices multidimensionales se verían como matrices (rectangulares) con un número definido de elementos en sus dimensiones (matrices internas), mientras que la matriz dentada sería como un calendario anual con las matrices internas que tienen un número diferente de elementos, como días en meses diferentes. Aunque las matrices irregulares son bastante complicadas y difíciles de usar debido a sus niveles anidados y no tienen mucha seguridad de tipos, pero son muy flexibles, le permiten manipular diferentes tipos de datos https://riptutorial.com/

30

Página 46 con bastante facilidad y no es necesario que contenga elementos vacíos o no utilizados.

Crear una matriz irregular En el siguiente ejemplo, inicializaremos una matriz dentada que contiene dos matrices, una para Nombres y otro para Números, y luego acceder a un elemento de cada Dim OuterArray () como variante Atenuar nombres () como variante Atenuar números () como variante 'las matrices se declaran como variantes para que podamos acceder a los atributos de cualquier tipo de datos a sus elementos

https://translate.googleusercontent.com/translate_f

39/223

6/1/2021

Intitulado Nombres = Matriz ("Persona1", "Persona2", "Persona3") Números = Matriz ("001", "002", "003") OuterArray = Array (nombres, números) 'Dar directamente a OuterArray una matriz que contiene matrices de Nombres y Números dentro Debug.Print OuterArray (0) (1) Debug.Print OuterArray (1) (1) 'acceder a elementos dentro del dentado dando las coordenadas del elemento

Creación y lectura dinámica de matrices irregulares También podemos ser más dinámicos en nuestro aproximado para construir las matrices, imagina que tenemos un hoja de datos del cliente en Excel y queremos construir una matriz para generar los detalles del cliente. Nombre - Teléfono - Correo electrónico - Número de cliente Persona1 - 153486231 - 1 @ STACK - 001 Persona2 - 153486242 - 2 @ STACK - 002 Persona3 - 153486253 - 3 @ STACK - 003 Persona4 - 153486264 - 4 @ STACK - 004 Persona5 - 153486275 - 5 @ STACK - 005

Construiremos dinámicamente una matriz de encabezado y una matriz de clientes, el encabezado contendrá el los títulos de las columnas y la matriz Clientes contendrán la información de cada cliente / fila como matrices. Atenuar encabezados como variante 'matriz de encabezados con la sección superior de la hoja de datos del cliente Para c = 1 a 4 Si está vacío (encabezados), entonces Encabezados ReDim (0) Encabezados (0) = Celdas (1, c) .Valor Más ReDim Preserve encabezados (0 a UBound (encabezados) + 1) Encabezados (UBound (Encabezados)) = Celdas (1, c) .Value Terminara si próximo Atenuar a los clientes como variante 'La matriz de clientes contendrá matrices de valores de cliente Atenuar Customer_Values como variante 'Customer_Values será una matriz del cliente en sus elementos (Nombre-Teléfono-Correo electrónico-CustNum)

https://riptutorial.com/

31

Página 47

Para r = 2 a 6 'iterar a través de los clientes / filas Para c = 1 a 4 'iterar a través de los valores / columnas 'construir una matriz que contenga los valores del cliente Si está vacío (Customer_Values), entonces ReDim Customer_Values (0) Customer_Values (0) = Celdas (r, c) .Value ElseIf Customer_Values (0) = "" Entonces Customer_Values (0) = Celdas (r, c) .Value Más ReDim Preserve Customer_Values (0 a UBound (Customer_Values) + 1) Customer_Values (UBound (Customer_Values)) = Celdas (r, c) .Value Terminara si próximo 'agregar la matriz customer_values a la matriz de clientes Si está vacío (clientes), entonces Clientes ReDim (0) Clientes (0) = Customer_Values Más ReDim Preserve Clientes (0 a UBound (Clientes) + 1) Clientes (UBound (Clientes)) = Customer_Values Terminara si

https://translate.googleusercontent.com/translate_f

40/223

6/1/2021

Intitulado 'restablecer Custumer_Values para reconstruir una nueva matriz si es necesario ReDim Customer_Values (0) próximo Dim Main_Array (0 a 1) como variante La matriz principal contendrá tanto los encabezados como los clientes. Main_Array (0) = Encabezados Main_Array (1) = Clientes

Para comprender mejor la forma de construir dinámicamente una matriz unidimensional, consulte Matrices dinámicas (cambio de tamaño de matriz y manejo dinámico) en la documentación de matrices.

El resultado del fragmento anterior es una matriz dentada con dos matrices, una de esas matrices con 4 elementos, 2 niveles de sangría, y el otro es en sí mismo otra matriz dentada que contiene 5 matrices de 4 elementos cada uno y 3 niveles de sangría, consulte la estructura a continuación: Main_Array (0) - Encabezados - Matriz ("Nombre", "Teléfono", "Correo electrónico", "Número de cliente") (1) - Clientes (0) - Matriz ("Persona1", 153486231, "1 @ STACK", 001) Clientes (1) - Array ("Person2", 153486242, "2 @ STACK", 002) ... Clientes (4) - Array ("Person5", 153486275, "5 @ STACK", 005)

Para acceder a la información tendrás que tener en cuenta la estructura del Jagged Array que creas, En el ejemplo anterior, puede ver que la matriz principal contiene una matriz de encabezados y una matriz de Matrices ( Clientes ) por lo tanto con diferentes formas de acceder a los elementos. Ahora leeremos la información del Main Array e imprimiremos la información de cada uno de los Clientes. como tipo de información: Info .

https://riptutorial.com/

32

Página 48

Para n = 0 a UBound (Main_Array (1)) 'n para iterar de la primera a la última matriz en Main_Array (1) Para j = 0 a UBound (Main_Array (1) (n)) 'j iterará del primero al último elemento en cada matriz de Main_Array (1) Debug.Print Main_Array (0) (j) & ":" & Main_Array (1) (n) (j) 'print Main_Array (0) (j) que es el encabezado y Main_Array (0) (n) (j) que es el elemento en la matriz de clientes 'podemos llamar al encabezado con j ya que la matriz de encabezado tiene la misma estructura que el matriz de clientes próximo próximo

RECUERDE realizar un seguimiento de la estructura de su Jagged Array, en el ejemplo anterior para acceder el Nombre de un cliente es accediendo a Main_Array -> Clientes -> CustomerNumber -> Name which tiene tres niveles, para devolver "Person4" necesitará la ubicación de los clientes en Main_Array, luego la Ubicación del cliente cuatro en la matriz de Clientes irregulares y, por último, la ubicación del elemento que necesita, en este caso Main_Array (1) (3) (0) que es Main_Array (Clientes) (CustomerNumber) (Nombre) .

Matrices multidimensionales

Matrices multidimensionales Como su nombre lo indica, las matrices multidimensionales son matrices que contienen más de una dimensión, generalmente dos o tres pero puede tener hasta 32 dimensiones.

https://translate.googleusercontent.com/translate_f

41/223

6/1/2021

Intitulado

Una matriz múltiple funciona como una matriz con varios niveles, tome en ejemplo una comparación entre uno, dos y tres dimensiones. One Dimension es su matriz típica, parece una lista de elementos. Dim 1D (3) como variante * 1D: visualmente * (0) (1) (2)

Dos dimensiones se verían como una cuadrícula de Sudoku o una hoja de Excel, al inicializar la matriz definiría cuántas filas y columnas tendría la matriz. Dim 2D (3,3) como variante 'esto resultaría en una cuadrícula de 3x3 * 2D: visualmente * (0,0) (0,1) (0,2) (1,0) (1,1) (1,2) (2,0) (2,1) (2,2)

https://riptutorial.com/

33

Página 49 Three Dimensions comenzaría a parecerse al cubo de Rubik, al inicializar la matriz definir filas y columnas y capas / profundidades que tendría la matriz. Dim 3D (3,3,2) como variante 'esto resultaría en una cuadrícula de 3x3x3 * 3D: visualmente * 1ra capa

Segunda capa

frente

Tercera capa

medio

espalda

(0,0,0) (0,0,1) (0,0,2) ¦ (1,0,0) (1,0,1) (1,0,2) ¦ (2,0,0 ) (2,0,1) (2,0,2) (0,1,0) (0,1,1) (0,1,2) ¦ (1,1,0) (1,1,1) (1,1,2) ¦ (2,1,0 ) (2,1,1) (2,1,2) (0,2,0) (0,2,1) (0,2,2) ¦ (1,2,0) (1,2,1) (1,2,2) ¦ (2,2,0 ) (2,2,1) (2,2,2)

Otras dimensiones podrían pensarse como la multiplicación del 3D, por lo que un 4D (1,3,3,3) sería dos matrices 3D en paralelo.

Matriz de dos dimensiones Creando El siguiente ejemplo será una compilación de una lista de empleados, cada empleado tendrá un conjunto de información de la lista (nombre, apellido, dirección, correo electrónico, teléfono ...), el ejemplo esencialmente se almacenará en la matriz (empleado, información) siendo el (0,0) el primer empleado primer nombre. Dim Bosses como variante 'establece jefes como Variante, para que podamos ingresar cualquier tipo de datos que queramos Jefes = [{"Jonh", "Snow", "Presidente"; "Ygritte", "Wild", "Vicepresidente"}] 'inicialice una matriz 2D directamente llenándola con información, el resultado será una matriz (1,2) tamaño 2x3 = 6 elementos Atenuar empleados como variante 'inicializa tu matriz de empleados como variante 'inicialice y ReDim la matriz de empleados para que sea una matriz dinámica en lugar de una estática, por lo tanto, tratado de manera diferente por el compilador de VBA Empleados de ReDim (100, 5) 'declarando una matriz 2D que puede almacenar 100 empleados con 6 elementos de información cada uno, pero comienza vacío 'el tamaño de la matriz es 101 x 6 y contiene 606 elementos

https://translate.googleusercontent.com/translate_f

42/223

6/1/2021

Intitulado Para empleado = 0 a UBound (empleados, 1) 'para cada empleado / fila en la matriz, UBound para matrices 2D, que obtendrá el último elemento en la matriz 'necesita dos parámetros, primero la matriz que verificar y segundo la dimensión, en este caso 1 = empleado y 2 = información Para información_e = 0 a UBound (empleados, 2) 'para cada elemento / columna de información de la matriz Empleados (empleado, información_e) = InformationNeeded 'InformationNeeded sería los datos para llenar la matriz 'iterar la matriz completa permitirá la atribución directa de información en el coordenadas del elemento próximo

https://riptutorial.com/

34

Página 50

próximo

Cambiar el tamaño Cambiar el tamaño o ReDim Preservar una matriz múltiple como la norma para una matriz de una dimensión obtendría un error, en cambio, la información debe transferirse a una matriz temporal con el mismo tamaño como el original más el número de filas / columnas para agregar. En el ejemplo siguiente veremos cómo inicializar una matriz temporal, transferir la información desde la matriz original, llenar el resto elementos vacíos y reemplace la matriz temporal por la matriz original. Dim TempEmp como variante 'inicializa tu matriz temporal como variante ReDim TempEmp (UBound (empleados, 1) + 1, UBound (empleados, 2)) 'ReDim / Resize Temp matriz como una matriz 2D con tamaño UBound (Empleados) +1 = (último elemento en Empleados 1a dimensión) + 1, 'la segunda dimensión sigue siendo la misma que la matriz original. efectivamente agregamos 1 fila en el Matriz de empleados 'transferir Para emp = LBound (empleados, 1) a UBound (empleados, 1) Para información = LBound (Empleados, 2) A UBound (Empleados, 2) 'para transferir empleados a TempEmp iteramos ambas matrices y llenamos TempEmp con el valor del elemento correspondiente en Empleados TempEmp (emp, info) = Empleados (emp, info) próximo próximo 'llenar restante 'después de las transferencias, la matriz Temp todavía tiene elementos no utilizados al final, ya que fue aumentado 'para llenar los elementos restantes, iterar desde la última "fila" con valores hasta la última fila en el formación 'en este caso, la última fila en Temp será el tamaño de las filas de la matriz Empleados + 1, ya que La última fila de la matriz de empleados ya está llena en TempArray Para emp = UBound (Empleados, 1) + 1 a UBound (TempEmp, 1) Para información = LBound (TempEmp, 2) To UBound (TempEmp, 2) TempEmp (emp, info) = InformationNeeded & "NewRow" próximo próximo 'borrar Empleados, atribuir la matriz Temp a Empleados y borrar la matriz Temp Borrar empleados Empleados = TempEmp Borrar TempEmp

Cambiar los valores de los elementos Para cambiar / alterar los valores en un determinado elemento se puede hacer simplemente llamando a la coordenada a cambiar y darle un nuevo valor: Empleados (0, 0) = "NewValue" https://translate.googleusercontent.com/translate_f

43/223

6/1/2021

Intitulado

Alternativamente, iterar a través de las condiciones de uso de coordenadas para hacer coincidir los valores correspondientes al parámetros necesarios: https://riptutorial.com/

35

Página 51

Para emp = 0 a UBound (empleados) Si Empleados (emp, 0) = "Gloria" Y Empleados (emp, 1) = "Stephan" Entonces 'si se encuentra el valor Empleados (emp, 1) = "Casado, cambio de apellido" Salir para 'no iterar a través de una matriz completa a menos que sea necesario Terminara si próximo

Leyendo

El acceso a los elementos de la matriz se puede hacer con un bucle anidado (iterando cada elemento), Loop and Coordinate (iterar filas y acceder a columnas directamente), o acceder directamente con ambas coordenadas. 'bucle anidado, iterará a través de todos los elementos Para emp = LBound (empleados, 1) a UBound (empleados, 1) Para información = LBound (Empleados, 2) A UBound (Empleados, 2) Debug.Print empleados (emp, info) próximo próximo 'bucle y coordina, iteración a través de todas las filas y en cada fila accediendo a todas las columnas directamente Para emp = LBound (empleados, 1) a UBound (empleados, 1) Debug.Print empleados (emp, 0) Debug.Print empleados (emp, 1) Debug.Print empleados (emp, 2) Debug.Print empleados (emp, 3) Empleados de Debug.Print (emp, 4) Debug.Print empleados (emp, 5) próximo 'acceder directamente al elemento con coordenadas Empleados de Debug.Print (5, 5)

Recuerde , siempre es útil mantener un mapa de matriz cuando se utilizan matrices multidimensionales, pueden convertirse fácilmente en confusión.

Matriz de tres dimensiones Para la matriz 3D, usaremos la misma premisa que la matriz 2D, con la adición de no solo almacenar el Empleado y la Información, pero también el Edificio en el que trabajan. La matriz 3D tendrá los Empleados (se puede considerar como Filas), la Información (Columnas), y edificios que se pueden considerar como hojas diferentes en un documento de Excel, tienen el mismo tamaño entre ellos, pero cada hoja tiene un conjunto diferente de información en sus celdas / elementos. El 3D matriz contendrá n número de matrices 2D. Creando

https://riptutorial.com/

36

Página 52

https://translate.googleusercontent.com/translate_f

44/223

6/1/2021

Intitulado

Una matriz 3D necesita 3 coordenadas para ser inicializada Dim 3Darray (2,5,5) Como Variante la primera coordenada en la matriz estará el número de Edificios / Hojas (diferentes conjuntos de filas y columnas), segundo La coordenada definirá Filas y terceras Columnas. La atenuación anterior dará como resultado una matriz 3D con 108 elementos ( 3 * 6 * 6 ), que efectivamente tienen 3 conjuntos diferentes de matrices 2D. Dim ThreeDArray como variante 'inicializa tu matriz ThreeDArray como variante ReDim ThreeDArray (1, 50, 5) 'declarando una matriz 3D que puede almacenar dos conjuntos de 51 empleados con 6 elementos de información cada uno, pero comienza vacío 'el tamaño de la matriz es 2 x 51 x 6 y contiene 612 elementos Para la construcción = 0 a UBound (ThreeDArray, 1) 'para cada edificio / conjunto de la matriz Para empleado = 0 a UBound (ThreeDArray, 2) 'para cada empleado / fila en la matriz Para información_e = 0 a UBound (ThreeDArray, 3) 'para cada elemento / columna de información de la matriz ThreeDArray (edificio, empleado, información_e) = Información necesaria ' La información necesaria serían los datos para llenar la matriz 'iterar la matriz completa permitirá la atribución directa de información en el coordenadas del elemento próximo próximo próximo

Cambiar el tamaño

Cambiar el tamaño de una matriz 3D es similar a cambiar el tamaño de una 2D, primero cree una matriz temporal con el mismo tamaño de el original agregando uno en la coordenada del parámetro a aumentar, la primera coordenada será aumentar el número de conjuntos en la matriz, la segunda y tercera coordenadas aumentarán el número de filas o columnas en cada conjunto. El siguiente ejemplo aumenta el número de Filas en cada conjunto en uno y llena las que se encuentran recientemente. elementos agregados con nueva información. Dim TempEmp como variante 'inicializa tu matriz temporal como variante ReDim TempEmp (UBound (ThreeDArray, 1), UBound (ThreeDArray, 2) + 1, UBound (ThreeDArray, 3)) 'ReDim / Resize Temp matriz como una matriz 3D con tamaño UBound (ThreeDArray) +1 = (último elemento en Empleados 2da dimensión) + 1, 'la otra dimensión sigue siendo la misma que la matriz original. efectivamente agregamos 1 fila en el para cada conjunto de la matriz 3D 'transferir Para construir = LBound (ThreeDArray, 1) To UBound (ThreeDArray, 1) Para emp = LBound (ThreeDArray, 2) To UBound (ThreeDArray, 2) Para información = LBound (ThreeDArray, 3) To UBound (ThreeDArray, 3) 'para transferir ThreeDArray a TempEmp iterando todos los conjuntos en la matriz 3D y llene TempEmp con el valor del elemento correspondiente en cada conjunto de cada fila TempEmp (edificio, emp, información) = ThreeDArray (edificio, emp, información) próximo próximo

https://riptutorial.com/

37

Página 53

próximo 'llenar restante 'para llenar los elementos restantes, necesitamos iterar desde la última "fila" con valores hasta la última fila en la matriz en cada conjunto, recuerde que el primer elemento vacío es la matriz original Hacia arriba () más 1 Para la construcción = LBound (TempEmp, 1) To UBound (TempEmp, 1) Para emp = UBound (ThreeDArray, 2) + 1 To UBound (TempEmp, 2) Para información = LBound (TempEmp, 3) a UBound (TempEmp, 3) TempEmp (edificio, emp, info) = InformationNeeded & "NewRow"

https://translate.googleusercontent.com/translate_f

45/223

6/1/2021

Intitulado próximo próximo próximo 'borrar Empleados, atribuir la matriz Temp a Empleados y borrar la matriz Temp Borrar ThreeDArray ThreeDArray = TempEmp Borrar TempEmp

Cambio de valores y lectura de elementos Leer y cambiar los elementos en la matriz 3D se puede hacer de manera similar a como lo hacemos Matriz 2D, solo ajuste el nivel extra en los bucles y coordenadas. Hacer 'usando Do ... While para salida anticipada Para la construcción = 0 a UBound (ThreeDArray, 1) Para emp = 0 a UBound (ThreeDArray, 2) Si ThreeDArray (edificio, emp, 0) = "Gloria" y ThreeDArray (edificio, emp, 1) = "Stephan" Entonces 'si se encuentra el valor ThreeDArray (building, emp, 1) = "Casado, cambio de apellido" Salir Hacer 'no iterar a través de toda la matriz a menos que sea necesario Terminara si próximo próximo Bucle en falso 'bucle anidado, iterará a través de todos los elementos Para construir = LBound (ThreeDArray, 1) To UBound (ThreeDArray, 1) Para emp = LBound (ThreeDArray, 2) To UBound (ThreeDArray, 2) Para información = LBound (ThreeDArray, 3) To UBound (ThreeDArray, 3) Debug.Print ThreeDArray (construcción, emp, información) próximo próximo próximo 'bucle y coordenada, iterará a través de todo el conjunto de filas y pedirá la fila más el valor elegimos para las columnas Para construir = LBound (ThreeDArray, 1) To UBound (ThreeDArray, 1) Para emp = LBound (ThreeDArray, 2) To UBound (ThreeDArray, 2) Debug.Print ThreeDArray (edificio, emp, 0) Debug.Print ThreeDArray (edificio, emp, 1) Debug.Print ThreeDArray (edificio, emp, 2) Debug.Print ThreeDArray (edificio, emp, 3) Debug.Print ThreeDArray (edificio, emp, 4)

https://riptutorial.com/

38

Página 54

Debug.Print ThreeDArray (edificio, emp, 5) próximo próximo 'acceder directamente al elemento con coordenadas Empleados de Debug.Print (0, 5, 5)

Leer matrices en línea: https://riptutorial.com/vba/topic/3064/arrays

https://translate.googleusercontent.com/translate_f

46/223

6/1/2021

Intitulado

https://riptutorial.com/

39

Página 55

Capítulo 4: Asignar cadenas con repetidas caracteres Observaciones A veces es necesario asignar una variable de cadena con un carácter específico que se repite en un numero de veces. VBA proporciona dos funciones principales para este propósito: • •

Cadena / Cadena $ Espacio / Espacio $ .

Ejemplos Utilice la función Cadena para asignar una cadena con n caracteres repetidos Dim lineOfHyphens como cadena 'Asignar una cadena con 80 guiones repetidos lineOfHyphens = String $ (80, "-")

Utilice las funciones String y Space para asignar una cadena de n caracteres Dim stringOfSpaces como cadena 'Asignar una cadena con 255 espacios repetidos usando Space $

https://translate.googleusercontent.com/translate_f

47/223

6/1/2021

Intitulado stringOfSpaces = Espacio $ (255) 'Asignar una cadena con 255 espacios repetidos usando String $ stringOfSpaces = String $ (255, "")

Lea Asignar cadenas con caracteres repetidos en línea: https://riptutorial.com/vba/topic/3581/assigning-strings-with-repeated-characters

https://riptutorial.com/

40

Página 56

Capítulo 5: Atributos Sintaxis • Atributo VB_Name = "ClassOrModuleName" • Atributo VB_GlobalNameSpace = False 'Ignorado • • • •

Atributo VB_Creatable = Falso 'Ignorado Atributo VB_PredeclaredId = {Verdadero | Falso} Atributo VB_Exposed = {Verdadero | Falso} Atributo variableName.VB_VarUserMemId = 0 'Cero indica que este es el valor predeterminado

miembro de la clase. • Attribute variableName.VB_VarDescription = "alguna cadena" 'Agrega el texto al objeto Información del navegador para esta variable. • Atributo procName.VB_Description = "alguna cadena" 'Agrega el texto al buscador de objetos información para el procedimiento. • Atributo procName.VB_UserMemId = {0 | -4} '0: Hace que la función sea el miembro predeterminado de la clase. '-4: especifica que la función devuelve un enumerador. ○



Ejemplos VB_Name VB_Name especifica la clase o el nombre del módulo. Atributo VB_Name = "Class1"

Se crearía una nueva instancia de esta clase con Atenuar myClass como Class1 myClass = nueva Class1

VB_GlobalNameSpace https://translate.googleusercontent.com/translate_f

48/223

6/1/2021

Intitulado

En VBA, este atributo se ignora. No se transfirió desde VB6. En VB6, crea una instancia global predeterminada de la clase (un "atajo") para que los miembros de la clase puedan ser accedido sin usar el nombre de la clase. Por ejemplo, DateTime (como en DateTime.Now ) es en realidad parte de la clase VBA.Conversion . Debug.Print VBA.Conversion.DateTime.Now Debug.Print DateTime.Now

VB_Createable

https://riptutorial.com/

41

Página 57 Este atributo se ignora. No se transfirió desde VB6. En VB6, se utilizó en combinación con el atributo VB_Exposed para controlar la accesibilidad de las clases. fuera del proyecto actual. VB_Exposed = Verdadero VB_Creatable = Verdadero

Daría como resultado una clase pública , a la que se podría acceder desde otros proyectos, pero esta funcionalidad no existe en VBA.

VB_PredeclaredId Crea una instancia predeterminada global de una clase. Se accede a la instancia predeterminada a través del nombre del clase.

Declaración VERSIÓN 1.0 CLASE EMPEZAR MultiUse = -1 'Verdadero FIN Atributo VB_Name = "Class1" Atributo VB_GlobalNameSpace = Falso Atributo VB_Creatable = Falso Atributo VB_PredeclaredId = True Atributo VB_Exposed = False Opción explícita Función pública GiveMeATwo () como entero GiveMeATwo = 2 Función final

Llamada Debug.Print Class1.GiveMeATwo

De alguna manera, esto simula el comportamiento de clases estáticas en otros lenguajes, pero a diferencia de otros idiomas, aún puede crear una instancia de la clase. Dim cls como Class1 Establecer cls = New Class1 Debug.Print cls.GiveMeATwo

VB_Exposed https://translate.googleusercontent.com/translate_f

49/223

6/1/2021

Intitulado

Controla las características de creación de instancias de una clase. Atributo VB_Exposed = False

https://riptutorial.com/

42

Página 58 Hace que la clase sea privada . No se puede acceder fuera del proyecto actual. Atributo VB_Exposed = True

Expone la clase Pública Ly, fuera del proyecto. Sin embargo, dado que VB_Createable se ignora en VBA, Las instancias de la clase no se pueden crear directamente. Esto es equivalente a la siguiente VB.Net clase. Clase pública Foo Friend Sub New () End Sub Clase final

Para obtener una instancia desde fuera del proyecto, debe exponer una fábrica para crear instancias. Una forma de hacerlo es con un módulo público normal . Función pública CreateFoo () como Foo CreateFoo = Nuevo Foo Función final

Dado que los módulos públicos son accesibles desde otros proyectos, esto nos permite crear nuevas instancias de nuestras clases públicas - no creables .

VB_Description Agrega una descripción de texto a un miembro de clase o módulo que se vuelve visible en el Explorador de objetos. Idealmente, todos los miembros públicos de una interfaz / API pública deberían tener una descripción. Función pública GiveMeATwo () como entero Attribute GiveMeATwo.VB_Description = "¡Devuelve un dos!" GiveMeATwo = 2 Propiedad final

Nota: todos los miembros de acceso de una propiedad ( Get , Let , Set ) usan la misma descripción.

VB_ [Var] UserMemId Se utilizan los atributos VB_VarUserMemId (para

variables de ámbito de módulo) y VB_UserMemId (para procedimientos) en VBA principalmente por dos cosas.

Especificar el miembro predeterminado de una clase Una clase List que encapsularía una colección querría tener una propiedad Item , por lo que el cliente

https://riptutorial.com/

43

Página 59

https://translate.googleusercontent.com/translate_f

50/223

6/1/2021

Intitulado

el código puede hacer esto: For i = 1 To myList.Count 'Los objetos de colección de VBA están basados en 1 Debug.Print myList.Item (i) próximo

Pero con un atributo VB_UserMemId establecido en 0 en la propiedad Item , el código del cliente puede hacer esto: For i = 1 To myList.Count 'Los objetos de colección de VBA están basados en 1 Debug.Print myList (i) próximo

Solo un miembro puede tener legalmente VB_UserMemId = 0 en una clase determinada. Para propiedades, especifique el atributo en el descriptor de acceso Get : Opción explícita Privado interno como nueva colección Propiedad pública Obtener recuento () siempre que Recuento = recuento interno Propiedad final Objeto de obtención de propiedad pública (índice ByVal tan largo) como variante Attribute Item.VB_Description = "Obtiene o establece el elemento en el índice especificado". Elemento de atributo.VB_UserMemId = 0 'Obtiene el elemento en el índice especificado. Elemento = interno (índice) Propiedad final Propiedad pública Let Item (ByVal index As Long, ByVal value As Variant) 'Establece el elemento en el índice especificado. Con interno Si index = .Count + 1 Entonces .Añadir elemento: = valor ElseIf index = .Count Then .Eliminar índice .Añadir elemento: = valor ElseIf index Referencias> Expresiones regulares de Microsoft VBScript #. # DLL asociado: VBScript.dll Fuente: Internet Explorer 1.0 y 5.5 • MSDN-Microsoft refuerza VBScript con expresiones regulares • Sintaxis de expresión regular de MSDN (secuencias de comandos) • expertos-exchange: uso de expresiones regulares en Visual Basic para aplicaciones y Visua l Básico 6 • Cómo usar expresiones regulares (Regex) en Microsoft Excel tanto en la celda como en bucles en SO. • regular-expressions.info/vbscript • regular-expressions.info/vbscriptexample • WIKI-Expresión regular

Código Puede utilizar estas funciones para obtener resultados RegEx, concatenar todas las coincidencias (si hay más de 1) en 1 cadena y muestra el resultado en la celda de Excel. Función pública getRegExResult (ByVal SourceString As String, Opcional ByVal RegExPattern As Cadena = "\ d +", _ ByVal opcional isGlobalSearch como booleano = True, ByVal opcional isCaseSensitive como booleano = Falso, delimitador ByVal opcional como cadena = ";") como cadena RegExObject estático como objeto Si RegExObject no es nada, entonces

https://translate.googleusercontent.com/translate_f

53/223

6/1/2021

Intitulado Establecer RegExObject = createVBScriptRegExObject Terminara si getRegExResult = removeLeadingDelimiter (concatObjectItems (getRegExMatches (RegExObject, SourceString, RegExPattern, isGlobalSearch, isCaseSensitive), Delimiter), Delimiter) Función final Función privada getRegExMatches (ByRef RegExObj como objeto, _ ByVal SourceString como cadena, ByVal RegExPattern como cadena, ByVal isGlobalSearch como Booleano, ByVal isCaseSensitive como booleano) como objeto Con RegExObj .Global = isGlobalSearch .IgnoreCase = Not (isCaseSensitive) 'es más fácil de usar usar un significado positivo de argumento, como isCaseSensitive, que usar IgnoreCase negativo .Patrón = RegExPattern Establecer getRegExMatches = .Execute (SourceString) Terminar con Función final Función privada concatObjectItems (ByRef Obj como objeto, ByVal DelimiterCustom opcional como String = ";") como cadena Atenuar objeto como variante Para cada objeto en el objeto concatObjectItems = concatObjectItems & DelimiterCustom & ObjElement.Value

https://riptutorial.com/

47

Página 63

próximo Función final Función pública removeLeadingDelimiter (ByVal SourceString como cadena, ByVal Delimiter como String) como cadena If Left $ (SourceString, Len (Delimiter)) = Delimiter Then removeLeadingDelimiter = Mid $ (SourceString, Len (Delimitador) + 1) Terminara si Función final Función privada createVBScriptRegExObject () como objeto Establecer createVBScriptRegExObject = CreateObject ("vbscript.RegExp") 'ej .: createVBScriptRegExObject.Pattern Función final

Objeto de sistema de archivos de secuencias de comandos Establecer createScriptingFileSystemObject = CreateObject ("Scripting.FileSystemObject")

Herramientas> Referencias> Microsoft Scripting Runtime DLL asociado: ScrRun.dll Fuente: sistema operativo Windows Acceso a archivos de MSDN con FileSystemObject El modelo de objetos del sistema de archivos (FSO) proporciona una herramienta basada en objetos para trabajar con carpetas y archivos. Le permite utilizar la sintaxis conocida de object.method con un rico conjunto de propiedades, métodos y eventos para procesar carpetas y archivos. También puede emplear el instrucciones y comandos tradicionales de Visual Basic. El modelo FSO le brinda a su aplicación la capacidad de crear, modificar, mover y eliminar carpetas, o para determinar si existen carpetas particulares y dónde existen. También le permite obtener información sobre carpetas, como sus nombres y la fecha en que fueron creadas o por última vez modificado. Temas de MSDN-FileSystemObject : " ... explicar el concepto de FileSystemObject y cómo usarlo. " exceltrick-FileSystemObject en VBA - Explicado Scripting.FileSystemObject https://translate.googleusercontent.com/translate_f

54/223

6/1/2021

Intitulado

Objeto Diccionario de secuencias de comandos Establecer dict = CreateObject ("Scripting.Dictionary")

Herramientas> Referencias> Microsoft Scripting Runtime DLL asociado: ScrRun.dll Fuente: sistema operativo Windows Objeto de scripting.Dictionary Objeto MSDN-Dictionary

https://riptutorial.com/

48

Página 64

Objeto de Internet Explorer Establecer createInternetExplorerObject = CreateObject ("InternetExplorer.Application")

Herramientas> Referencias> Controles de Internet de Microsoft DLL asociado: ieframe.dll Fuente: navegador Internet Explorer Objeto MSDN-InternetExplorer Controla una instancia de Windows Internet Explorer mediante la automatización.

Miembros básicos de Internet Explorer Objec El siguiente código debería presentar cómo funciona el objeto IE y cómo manipularlo a través de VBA. yo recomiendo recorrerlo, de lo contrario, podría producirse un error durante varias navegaciones. Sub IEGetToKnow () Atenuar IE como referencia de InternetExplorer a los controles de Internet de Microsoft Establecer IE = New InternetExplorer Con IE .Visible = True 'Establece u obtiene un valor que indica si el objeto es visible o oculto. 'Navegación .Navigate2 "http://www.example.com" 'Navega el navegador a una ubicación que no puede expresarse como una URL, como un PIDL para una entidad en el espacio de nombres de Windows Shell. Debug.Print .Busy 'Obtiene un valor que indica si el objeto está involucrado en un operación de navegación o descarga. Debug.Print .ReadyState 'Obtiene el estado listo del objeto. .Navigate2 "http://www.example.com/2" .GoBack 'Navega hacia atrás un elemento en la lista del historial .GoForward 'Avanza un elemento en la lista del historial. .GoHome 'Navega a la página de inicio o de inicio actual. .Stop 'Cancela una navegación o descarga pendiente y detiene los elementos dinámicos de la página, como como sonidos de fondo y animaciones. .Refresh 'Vuelve a cargar el archivo que se muestra actualmente en el objeto. Debug.Print .Silent 'Establece u obtiene un valor que indica si el objeto puede mostrar cuadros de diálogo. Debug.Print .Type 'Obtiene el nombre del tipo de usuario del objeto de documento contenido. Debug.Print .Top 'Establece u obtiene las coordenadas del borde superior del objeto. Debug.Print .Left 'Establece u obtiene las coordenadas del borde izquierdo del objeto. Debug.Print .Height 'Establece u obtiene la altura del objeto. Debug.Print .Width 'Establece u obtiene el ancho del objeto. Terminar con IE.Quit 'cierra la ventana de la aplicación End Sub

https://translate.googleusercontent.com/translate_f

55/223

6/1/2021

Intitulado

Raspado web https://riptutorial.com/

49

Página 65 Lo más común que se puede hacer con IE es extraer información de un sitio web o completar un formulario del sitio web y enviar información. Veremos cómo hacerlo. Dejenos considerar código fuente de example.com :

Dominio de ejemplo

") 'concatenatedString = "foo> bar> fizz" 'Concatenar con Join y separar cada elemento con una cadena de ancho cero concatenatedString = VBA.Strings.Join (widgetNames, vbNullString) 'concatenatedString = "foobarfizz"

Leer Concatenación de cadenas en línea: https://riptutorial.com/vba/topic/3580/concatenating-strings

https://translate.googleusercontent.com/translate_f

67/223

6/1/2021

Intitulado

https://riptutorial.com/

63

Página 79

Capítulo 10: Compilación condicional Ejemplos Cambiar el comportamiento del código en tiempo de compilación La directiva #Const se usa para definir una constante de preprocesador personalizada. Estos pueden ser utilizados posteriormente por #Si controlar

qué bloques de código se compilan y ejecutan.

#Const DEBUGMODE = 1 #Si DEBUGMODE Entonces Const filepath As String = "C: \ Users \ UserName \ Path \ To \ File.txt" #Más Ruta de archivo constante como cadena = "\\ servidor \ recurso compartido \ ruta \ a \ archivo.txt" #Terminara si

Esto da como resultado que el valor de la ruta de archivo se establezca en "C: \ Users \ UserName \ Path \ To \ File.txt" . Eliminando la línea #Const , o cambiarla a #Const DEBUGMODE = 0 daría como resultado que la ruta del archivo se establezca en "\\ servidor \ recurso compartido \ ruta \ a \ archivo.txt" .

#Const alcance La directiva #Const solo es efectiva para un solo archivo de código (módulo o clase). Debe ser declarado para todos y cada uno de los archivos en los que desea utilizar su constante personalizada. Alternativamente, puede declarar un #Const globalmente

para su proyecto yendo a Herramientas >> [Nombre de su proyecto] Propiedades del proyecto. Esta Aparecerá el cuadro de diálogo de propiedades del proyecto donde ingresaremos la declaración constante. En el En el cuadro “Argumentos de compilación condicional”, escriba [constName] = [value] . Puede ingresar más de 1 constante separándolos con dos puntos, como [constName1] = [value1]: [constName2] = [value2] .

https://riptutorial.com/ https://translate.googleusercontent.com/translate_f

64 68/223

6/1/2021

Intitulado

Página 80

Constantes predefinidas Algunas constantes de compilación ya están predefinidas. Cuales existen dependerán del bitness de la versión de Office en la que está ejecutando VBA. Tenga en cuenta que Vba7 se introdujo junto con Office 2010 para admitir versiones de 64 bits de Office. Constante de 16 bits 32 bits 64 bits Vba6

Falso Si Vba6 Falso

Vba7

Falso si Vba7 es verdadero

Win16

Cierto

Win32

Falso verdadero

Cierto

Win64

Falso falso

Cierto

Mac

Falso si Mac

Si Mac

Falso

Falso

Tenga en cuenta que Win64 / Win32 se refiere a la versión de Office, no a la versión de Windows. Por ejemplo Win32 = VERDADERO en Office de 32 bits, incluso si el sistema operativo es una versión de Windows de 64 bits.

Uso de Declare Importaciones que funcionan en todas las versiones de Office #Si Vba7 Entonces 'Es importante verificar primero Win64, 'porque Win32 también devolverá verdadero cuando Win64 lo haga. #Si Win64 Entonces

https://riptutorial.com/

sesenta y cinco

Página 81

Declare la función PtrSafe GetFoo64 Lib "exampleLib32" () como LongLong #Más Declare la función PtrSafe GetFoo Lib "exampleLib32" () As Long #Terminara si #Más 'Debe ser Vba6, la palabra clave PtrSafe no existía en ese entonces, ', por lo que debemos declarar las importaciones de Win32 de manera un poco diferente a la anterior.

https://translate.googleusercontent.com/translate_f

69/223

6/1/2021

Intitulado #Si Win32 entonces Declarar función GetFoo Lib "exampleLib32" () As Long #Más Declare la función GetFoo Lib "exampleLib" () como entero #Terminara si #Terminara si

Esto se puede simplificar un poco según las versiones de Office que necesite admitir. por Por ejemplo, todavía no hay mucha gente compatible con las versiones de Office de 16 bits. La última versión de 16 bi t office fue la versión 4.3, lanzada en 1994 , por lo que la siguiente declaración es suficiente para casi todos casos modernos (incluido Office 2007). #Si Vba7 Entonces 'Es importante verificar primero Win64, 'porque Win32 también devolverá verdadero cuando Win64 lo haga. #Si Win64 Entonces Declare la función PtrSafe GetFoo64 Lib "exampleLib32" () como LongLong #Más Declare la función PtrSafe GetFoo Lib "exampleLib32" () As Long #Terminara si #Más 'Debe ser Vba6. No admitimos Office de 16 bits, por lo que debe ser Win32. Declarar función GetFoo Lib "exampleLib32" () As Long #Terminara si

Si no tiene que admitir nada anterior a Office 2010, esta declaración funciona bien. 'Solo tenemos instalaciones de 2010, por lo que ya sabemos que tenemos Vba7. #Si Win64 Entonces Declare la función PtrSafe GetFoo64 Lib "exampleLib32" () como LongLong #Más Declare la función PtrSafe GetFoo Lib "exampleLib32" () As Long #Terminara si

Lea la compilación condicional en línea: https://riptutorial.com/vba/topic/3364/conditional-compilation

https://riptutorial.com/

66

Página 82

Capítulo 11: Conversión de otros tipos a cadenas Observaciones VBA convertirá implícitamente algunos tipos en cadenas según sea necesario y sin ningún trabajo adicional en el parte del programador, pero VBA también proporciona una serie de funciones explícitas de conversión de cadenas, y también puedes escribir el tuyo propio. Tres de las funciones más utilizadas son CStr , Format y StrConv .

Ejemplos https://translate.googleusercontent.com/translate_f

70/223

6/1/2021

Intitulado

Utilice CStr para convertir un tipo numérico en una cadena Const zipCode As Long = 10012 Dim zipCodeText como cadena 'Convierta el número zipCode en una cadena de caracteres de dígitos zipCodeText = CStr (código postal) 'zipCodeText = "10012"

Utilice Formato para convertir y formatear un tipo numérico como una cadena Const zipCode Siempre que = 10012 Dim zeroPaddedNumber como cadena zeroPaddedZipCode = Formato (zipCode, "00000000") 'zeroPaddedNumber = "00010012"

Utilice StrConv para convertir una matriz de bytes de caracteres de un solo byte en una cadena 'Declare una matriz de bytes, asigne códigos de caracteres de un solo byte y convierta a una cadena Dim singleByteChars (4) Como Byte singleByteChars (0) = 72 singleByteChars (1) = 101 singleByteChars (2) = 108 singleByteChars (3) = 108 singleByteChars (4) = 111 Dim stringFromSingleByteChars como cadena stringFromSingleByteChars = StrConv (singleByteChars, vbUnicode) 'stringFromSingleByteChars = "Hola"

Convierta implícitamente una matriz de bytes de caracteres de varios bytes en una cadena 'Declare una matriz de bytes, asigne códigos de caracteres multibyte y convierta a una cadena Dim multiByteChars (9) como byte multiByteChars (0) = 87 multiByteChars (1) = 0 multiByteChars (2) = 111 multiByteChars (3) = 0

https://riptutorial.com/

67

Página 83

multiByteChars (4) = 114 multiByteChars (5) = 0 multiByteChars (6) = 108 multiByteChars (7) = 0 multiByteChars (8) = 100 multiByteChars (9) = 0 Dim stringFromMultiByteChars como cadena stringFromMultiByteChars = multiByteChars 'stringFromMultiByteChars = "Mundo"

Leer Conversión de otros tipos a cadenas en línea: https://riptutorial.com/vba/topic/3467/convertingotros-tipos-a-cadenas

https://translate.googleusercontent.com/translate_f

71/223

6/1/2021

Intitulado

https://riptutorial.com/

68

Página 84

Capítulo 12: Copiar, devolver y pasar matrices Ejemplos Copiar matrices Puede copiar una matriz VBA en una matriz del mismo tipo utilizando el operador = . Las matrices deben ser del mismo tipo, de lo contrario, el código arrojará un error de compilación "No se puede asignar a la matriz". Fuente de atenuación (0 a 2) siempre que Destino atenuadoLong () Tan Long Destino atenuado Doble () como doble destinationLong = source 'copia el contenido de la fuente en destinationLong destinationDouble = source 'no se compila

La matriz de origen puede ser fija o dinámica, pero la matriz de destino debe ser dinámica. Tratando de copiar a una matriz fija arrojará un error de compilación "No se puede asignar a la matriz". Cualquier dato preexistente en la matriz receptora se pierde y sus límites y dimensiones se cambian a los mismos que los de la fuente formación. Fuente atenuada () siempre que Fuente ReDim (0 a 2) Dim fijo (0 a 2) siempre que Dim dynamic () tan largo fijo = fuente 'no se compila dynamic = source 'se compila Dim dynamic2 () tan largo ReDim dynamic2 (0 a 6, 3 a 99)

https://translate.googleusercontent.com/translate_f

72/223

6/1/2021

Intitulado dynamic2 = source 'dynamic2 ahora tiene dimensión (0 a 2)

Una vez que se realiza la copia, las dos matrices se separan en la memoria, es decir, las dos variables no se referencias a los mismos datos subyacentes, por lo que los cambios realizados en una matriz no aparecen en la otra. Fuente atenuada (0 a 2) siempre que Destino atenuado () tan largo fuente (0) = 3 fuente (1) = 1 fuente (2) = 4 destino = fuente destino (0) = 2 Fuente de Debug.Print (0); fuente (1); fuente (2)

'salidas: 3 1 4

https://riptutorial.com/

69

Página 85

Debug.Print destino (0); destino (1); destino (2) 'salidas: 2 1 4

Copiar matrices de objetos Con matrices de objetos , se copian las referencias a esos objetos, no los objetos en sí. Si un se realiza un cambio en un objeto en una matriz, también parecerá que se ha cambiado en la otra matriz; ambos hacen referencia al mismo objeto. Sin embargo, configurar un elemento en un objeto diferente en una array no lo establecerá en ese objeto el otro array. Fuente atenuada (0 a 2) como rango Destino atenuado () como rango Establecer fuente (0) = Rango ("A1"): fuente (0) .Valor = 3 Establecer fuente (1) = Rango ("A2"): fuente (1) .Valor = 1 Establecer fuente (2) = Rango ("A3"): fuente (2) .Valor = 4 destino = fuente Establecer destino (0) = La referencia de rango ("A4") 'cambió en el destino pero no en la fuente destino (0) .Value = 2

'afecta a un objeto solo en destino

destino (1) .Valor = 5

'afecta a un objeto tanto en origen como en destino

Fuente de Debug.Print (0); fuente (1); fuente (2)

'salidas 3 5 4

Debug.Print destino (0); destino (1); destino (2) 'salidas 2 5 4

Variantes que contienen una matriz También puede copiar una matriz en y desde una variable variante. Al copiar de una variante, debe contener una matriz del mismo tipo que la matriz receptora, de lo contrario arrojará una "Falta de coincidencia de tipos" Error de tiempo de ejecución. Dim var como variante Fuente atenuada (0 a 2) como rango Destino atenuado () como rango var = fuente destino = var var = 5 destino = var 'arroja un error de tiempo de ejecución

Devolución de matrices de funciones

https://translate.googleusercontent.com/translate_f

73/223

6/1/2021

Intitulado

Una función en un módulo normal (pero no un módulo de clase) puede devolver una matriz poniendo () después de la tipo de datos. Función arrayOfPiDigits () As Long () Dim outputArray (0 a 2) tan largo outputArray (0) = 3

https://riptutorial.com/

70

Página 86

outputArray (1) = 1 outputArray (2) = 4 arrayOfPiDigits = outputArray Función final

El resultado de la función se puede colocar en una matriz dinámica del mismo tipo o variante. los También se puede acceder directamente a los elementos utilizando un segundo conjunto de corchetes, sin embargo, esto llamará la función cada vez, por lo que es mejor almacenar los resultados en una nueva matriz si planea usarlos más de una vez Sub arrayExample () Destino atenuado () tan largo Dim var como variante destino = arrayOfPiDigits () var = arrayOfPiDigits Destino de debug.Print (0)

'salidas 3

Debug.Print var (1)

'salidas 1

Debug.Print arrayOfPiDigits () (2) 'salidas 4 End Sub

Tenga en cuenta que lo que se devuelve es en realidad una copia de la matriz dentro de la función, no una referencia. Así que si la función devuelve el contenido de una matriz estática, sus datos no pueden ser cambiados por la llamada procedimiento.

Salida de una matriz a través de un argumento de salida Normalmente es una buena práctica de codificación que los argumentos de un procedimiento sean entradas y salidas a través del valor de retorno. Sin embargo, las limitaciones de VBA a veces hacen necesario que un procedimiento datos de salida a través de un argumento ByRef .

Salida a una matriz fija Sub threePiDigits (destino ByRef () tan largo) destino (0) = 3 destino (1) = 1 destino (2) = 4 End Sub Sub printPiDigits () Dim dígitos (0 a 2) tan largos dígitos de threePiDigits Debug.Print dígitos (0); dígitos (1); dígitos (2) 'salidas 3 1 4 End Sub

https://riptutorial.com/ https://translate.googleusercontent.com/translate_f

71 74/223

6/1/2021

Intitulado

Página 87

Salida de una matriz desde un método de clase Un argumento de salida también se puede usar para generar una matriz de un método / procedimiento en una clase módulo 'Módulo de clase' MathConstants ' Sub threePiDigits (destino ByRef () tan largo) Destino ReDim (0 a 2) destino (0) = 3 destino (1) = 1 destino (2) = 4 End Sub 'Módulo de código estándar Sub printPiDigits () Dim dígitos () tan largos Dim mathConsts como nuevas MathConstants mathConsts.threePiDigits dígitos Debug.Print dígitos (0); dígitos (1); dígitos (2) 'salidas 3 1 4 End Sub

Pasar matrices a procedimientos Las matrices se pueden pasar a los procedimientos poniendo () después del nombre de la variable de matriz. Función countElements (ByRef arr () As Double) As Long countElements = UBound (arr) - LBound (arr) + 1 Función final

Las matrices deben pasarse por referencia. Si no se especifica ningún mecanismo de paso, por ejemplo, myFunction (arr ()) , entonces VBA asumirá ByRef de forma predeterminada, sin embargo, es una buena práctica de codificación hacerlo explícito. Intentar pasar una matriz por valor, por ejemplo, myFunction (ByVal arr ()) resultará en un "argumento de matriz debe ser un error de compilación ByRef "(o un error de compilación" Error de sintaxis "si la comprobación automática de sintaxis no está marcado en las opciones de VBE). Pasar por referencia significa que cualquier cambio en la matriz se conservará en la llamada proceder. Sub testArrayPassing () Fuente de atenuación (0 a 1) siempre que fuente (0) = 3 fuente (1) = 1 Debug.Print doubleAndSum (fuente) 'salidas 8 Fuente de Debug.Print (0); fuente (1) 'salidas 6 2 End Sub Función doubleAndSum (ByRef arr () As Long) arr (0) = arr (0) * 2 arr (1) = arr (1) * 2 doubleAndSum = arr (0) + arr (1)

https://riptutorial.com/

72

Página 88

Función final

Si desea evitar cambiar la matriz original, tenga cuidado de escribir la función para que no cambia ningún elemento. https://translate.googleusercontent.com/translate_f

75/223

6/1/2021

Intitulado Función doubleAndSum (ByRef arr () As Long) doubleAndSum = arr (0) * 2 + arr (1) * 2 Función final

Alternativamente, cree una copia de trabajo de la matriz y trabaje con la copia. Función doubleAndSum (ByRef arr () As Long) Dim copyOfArr () tan largo copyOfArr = arr copyOfArr (0) = copyOfArr (0) * 2 copyOfArr (1) = copyOfArr (1) * 2 doubleAndSum = copyOfArr (0) + copyOfArr (1) Función final

Lea Copiar, devolver y pasar matrices en línea: https://riptutorial.com/vba/topic/9069/copying-matrices de retorno y paso

https://riptutorial.com/

73

Página 89

Capítulo 13: CreateObject frente a GetObject Observaciones En su forma más simple, CreateObject crea una instancia de un objeto mientras que GetObject obtiene una existente instancia de un objeto. Determinar si un objeto se puede crear u obtener dependerá de su Propiedad de instancia . Algunos objetos son SingleUse (por ejemplo, WMI) y no se pueden crear si ya existe. Otros objetos (por ejemplo, Excel) son MultiUse y permiten que se ejecuten varias instancias a la vez. Si una instancia de un objeto aún no existe e intenta GetObject , recibirá el siguiente mensaje capturable: Error en tiempo de ejecución '429': el componente ActiveX no puede crear el objeto . GetObject requiere que esté presente al menos uno de estos dos parámetros opcionales: https://translate.googleusercontent.com/translate_f

76/223

6/1/2021

Intitulado

1. Pathname - Variant (String): La ruta completa, incluido el nombre de archivo, del archivo que contiene el objeto. Este parámetro es opcional, pero se requiere Class si se omite Pathname . 2. Clase - Variante (Cadena): Una cadena que representa la definición formal (Aplicación y ObjectType) del objeto. Se requiere la clase si se omite Pathname .

CreateObject tiene un parámetro obligatorio y un parámetro opcional: 1. Clase - Variante (Cadena): Una cadena que representa la definición formal (Aplicación y ObjectType) del objeto. La clase es un parámetro obligatorio. 2. Servername - Variant (String): El nombre de la computadora remota en la que se ubicará el objeto. creado. Si se omite, el objeto se creará en la máquina local.

La clase siempre consta de dos partes en forma de Application.ObjectType : 1. Aplicación : el nombre de la aplicación de la que forma parte el objeto. | 2. Tipo de objeto : el tipo de objeto que se está creando. | Algunas clases de ejemplo son: 1. Word.Application 2. Hoja de Excel 3. Scripting.FileSystemObject

Ejemplos Demostrar GetObject y CreateObject Función MSDN-GetObject Devuelve una referencia a un objeto proporcionado por un componente ActiveX. Utilice la función GetObject cuando haya una instancia actual del objeto o si lo desea

https://riptutorial.com/

74

Página 90 para crear el objeto con un archivo ya cargado. Si no hay una instancia actual y usted no quiere que el objeto comience con un archivo cargado, use la función CreateObject. Sub CreateVSGet () Dim ThisXLApp As Excel.Application 'Un ejemplo de enlace anticipado Dim AnotherXLApp As Object 'Un ejemplo de enlace tardío Atenuar ThisNewWB como libro de trabajo Atenuar otroNuevoWB como libro de trabajo Dim wb como libro de trabajo 'Obtener esta instancia de Excel Establecer ThisXLApp = GetObject (ThisWorkbook.Name) .Application 'Crea otra instancia de Excel Establecer AnotherXLApp = CreateObject ("Excel.Application") 'Hacer visible la segunda instancia AnotherXLApp.Visible = True 'Agregar un libro de trabajo a la segunda instancia Establecer AnotherNewWB = AnotherXLApp.Workbooks.Add 'Agregar una hoja a la segunda instancia AnotherNewWB.Sheets.Add 'Ahora debería tener 2 instancias de Excel abiertas 'La primera instancia tiene 1 libro de trabajo: Libro1 'La segunda instancia tiene 1 libro de trabajo: Libro2 'Vamos a agregar otro libro de trabajo a nuestra primera instancia Establecer ThisNewWB = ThisXLApp.Workbooks.Add 'Ahora recorra los libros de trabajo y muestre sus nombres

https://translate.googleusercontent.com/translate_f

77/223

6/1/2021

Intitulado Para cada wb en ThisXLApp.Workbooks Debug.Print wb.Name próximo 'Ahora la primera instancia tiene 2 libros de trabajo: Libro1 y Libro3 'Si cierra la primera instancia de Excel, 'Book1 y Book3 se cerrarán, pero book2 seguirá abierto End Sub

Lea CreateObject frente a GetObject en línea: https://riptutorial.com/vba/topic/7729/createobject-vs-getobject

https://riptutorial.com/

75

Página 91

Capítulo 14: Creación de una clase personalizada Observaciones Este artículo mostrará cómo crear una clase personalizada completa en VBA. Utiliza el ejemplo de un DateRange ,

porque las fechas de inicio y finalización a menudo se pasan juntas a las funciones.

Ejemplos Agregar una propiedad a una clase Un procedimiento de propiedad es una serie de instrucciones que recupera o modifica una propiedad personalizada en un módulo. Hay tres tipos de accesores de propiedad: 1. Un procedimiento Get que devuelve el valor de una propiedad. 2. Un procedimiento Let que asigna un valor (no objeto ) a un objeto. 3. Un procedimiento de conjunto que asigna una referencia de objeto . Los descriptores de acceso a las propiedades a menudo se definen en pares, utilizando tanto Get como Let / Set para cada propiedad. UN la propiedad con solo un procedimiento Get sería de solo lectura, mientras que una propiedad con solo un Let / Set El procedimiento sería de solo escritura. En el siguiente ejemplo, se definen cuatro descriptores de acceso a la propiedad para la clase DateRange : 1.

StartDate (

2.

EndDate (

lectura / escritura ). Valor de fecha que representa la fecha anterior en un rango. Cada procedimiento usa el valor de la variable del módulo, mStartDate . lectura / escritura ). Valor de fecha que representa la fecha posterior en un rango. Cada procedimiento utiliza el valor de la variable del módulo, mEndDate .

https://translate.googleusercontent.com/translate_f

78/223

6/1/2021

Intitulado

3.

DaysBetween (

4.

RangeToCopy (

solo lectura ). Valor entero calculado que representa el número de días entre las dos fechas. Debido a que solo hay un procedimiento Get , esta propiedad no se puede modificar directamente. solo escritura ). Un procedimiento Set utilizado para copiar los valores de un DateRange existente

objeto. Privado mStartDate como fecha

'Variable del módulo para contener la fecha de inicio

Privado mEndDate como fecha

'Variable de módulo para contener la fecha de finalización

'Devuelve el valor actual de la fecha de inicio Propiedad pública Get StartDate () como fecha StartDate = mStartDate Propiedad final 'Establezca el valor de la fecha de inicio. Tenga en cuenta que dos métodos tienen el nombre StartDate Propiedad pública Let StartDate (ByVal NewValue As Date) mStartDate = NewValue Propiedad final

https://riptutorial.com/

76

Página 92

Lo mismo, pero para la fecha de finalización Propiedad pública Obtener EndDate () como fecha EndDate = mEndDate Propiedad final Propiedad pública Let EndDate (ByVal NewValue como fecha) mEndDate = NewValue Propiedad final 'Propiedad de solo lectura que devuelve el número de días entre las dos fechas Propiedad pública Obtener DaysBetween () como entero DaysBetween = DateDiff ("d", mStartDate, mEndDate) Función final 'Propiedad de solo escritura que pasa una referencia de objeto de un rango para clonar Conjunto de propiedades públicas RangeToCopy (ByRef ExistingRange como DateRange) Me.StartDate = ExistingRange.StartDate Me.EndDate = ExistingRange.EndDate Propiedad final

Agregar funcionalidad a una clase Cualquier sub , función o propiedad pública dentro de un módulo de clase se puede llamar antes de la llamada con una referencia de objeto: Objeto.Procedimiento

En una clase DateRange , un Sub podría usarse para agregar un número de días a la fecha de finalización: Public Sub AddDays (ByVal NoDays como entero) mEndDate = mEndDate + NoDays End Sub

Una función podría devolver el último día del próximo fin de mes (tenga en cuenta que GetFirstDayOfMonth no ser visible fuera de la clase porque es privado): Función pública GetNextMonthEndDate () como fecha GetNextMonthEndDate = DateAdd ("m", 1, GetFirstDayOfMonth ()) Función final Función privada GetFirstDayOfMonth () como fecha GetFirstDayOfMonth = DateAdd ("d", -DatePart ("d", mEndDate), mEndDate) Función final

https://translate.googleusercontent.com/translate_f

79/223

6/1/2021

Intitulado

Los procedimientos pueden aceptar argumentos de cualquier tipo, incluidas referencias a objetos de la clase que se definido. El siguiente ejemplo prueba si el objeto DateRange actual tiene una fecha de inicio y una finalización fecha que incluye la fecha de inicio y finalización de otro objeto DateRange .

https://riptutorial.com/

77

Página 93

Función pública ContainsRange (ByRef TheRange como DateRange) como booleano ContainsRange = TheRange.StartDate> = Me.StartDate y TheRange.EndDate Clase1 Opción explícita Public PublicField siempre que

'> Módulo1 Opción explícita Sub público DoSomething () 'Class1.PublicField no significa nada aquí Con New Class1 .PublicField = 42 Terminar con 'Class1.PublicField no significa nada aquí End Sub

Encapsular campos Los datos de instancia a menudo se mantienen privados y se denominan encapsulados . Un campo privado puede quedar expuesto utilizando un procedimiento de propiedad . Para exponer una variable privada públicamente sin dar acceso de escritura a la llamador, un módulo de clase (o un módulo estándar) implementa un miembro Property Get : Opción explícita Privado encapsulado siempre que

https://riptutorial.com/

107

Página 123

https://translate.googleusercontent.com/translate_f

105/223

6/1/2021

Intitulado Propiedad pública Get SomeValue () mientras SomeValue = encapsulado Propiedad final Sub público DoSomething () encapsulado = 42 End Sub

La clase en sí puede modificar el valor encapsulado, pero el código de llamada solo puede acceder al Public miembros (y miembros amigos , si la persona que llama está en el mismo proyecto). Para permitir que la persona que llama modifique: • Un valor encapsulado , un módulo expone un miembro Property Let . • Una referencia de objeto encapsulado , un módulo expone un miembro del conjunto de propiedades .

Constantes (Const) Si tiene un valor que nunca cambia en su aplicación, puede definir una constante con nombre y utilícelo en lugar de un valor literal. Puede usar Const solo a nivel de módulo o procedimiento. Esto significa el contexto de declaración para un la variable debe ser una clase, estructura, módulo, procedimiento o bloque, y no puede ser un archivo fuente, espacio de nombres o interfaz. Public Const GLOBAL_CONSTANT As String = "Versión del proyecto # 1.000.000.001" Private Const MODULE_CONSTANT As String = "Algo relevante para este módulo" Declaración de subejemplo público () Const SOME_CONSTANT As String = "Hola mundo" Const PI como doble = 3,141592653 End Sub

Si bien se puede considerar una buena práctica especificar tipos de constantes, no es estrictamente necesario. No especificar el tipo aún resultará en el tipo correcto: Public Const GLOBAL_CONSTANT = "Versión del proyecto # 1.000.000.001" 'Sigue siendo una cadena Declaración de subejemplo público () Const SOME_CONSTANT = "Hola mundo"

'Todavía una cuerda

Const DERIVED_CONSTANT = SOME_CONSTANT

'DERIVED_CONSTANT también es una cadena

Const VAR_CONSTANT como variante = SOME_CONSTANT 'VAR_CONSTANT es variante / cadena Const PI = 3,141592653

'Todavía un doble

Const DERIVED_PI = PI

'DERIVED_PI también es un doble

Const VAR_PI como variante = PI 'VAR_PI es variante / doble End Sub

Tenga en cuenta que esto es específico de las constantes y en contraste con las variables donde no se especifica el tipo

https://riptutorial.com/

108

Página 124 da como resultado un tipo de variante. Si bien es posible declarar explícitamente una constante como una cadena, no es posible declarar una constante como una cadena usando sintaxis de cadena de ancho fijo 'Esta es una constante de cadena de 5 caracteres válida Const FOO como cadena = "ABCDE" 'Esta no es una sintaxis válida para una constante de cadena de 5 caracteres Const FOO como cadena * 5 = "ABCDE"

https://translate.googleusercontent.com/translate_f

106/223

6/1/2021

Intitulado

Modificadores de acceso La instrucción Dim debe reservarse para variables locales. A nivel de módulo, prefiera el acceso explícito modificadores: • • •

Privado para



Global también

Público para

campos privados, a los que solo se puede acceder dentro del módulo en el que están declarados. campos públicos y variables globales, a las que se puede acceder mediante cualquier código de llamada.

Amigo de

las variables públicas dentro del proyecto, pero inaccesible a otros VBA de referencia proyectos (relevante para complementos) se puede usar para campos públicos en módulos estándar, pero es ilegal en módulos de clase y es obsoleto de todos modos - prefiera el modificador Público en su lugar. Este modificador no es legal para procedimientos tampoco.

Los modificadores de acceso son aplicables tanto a variables como a procedimientos. Módulo privado Variable como cadena Public GlobalVariable como cadena Procedimiento de submódulo privado () ModuleVariable = "Esto solo se puede hacer desde el mismo módulo" End Sub Procedimiento sub global público () GlobalVariable = "Esto se puede hacer desde cualquier módulo dentro de este proyecto" End Sub

Opción Módulo Privado Los procedimientos Sub públicos sin parámetros en módulos estándar se exponen como macros y pueden adjunto a los controles y atajos de teclado en el documento anfitrión. Por el contrario, los procedimientos de función pública en módulos estándar se exponen como definidos por el usuario funciones (UDF) en la aplicación host. Especificar Option Private Module en la parte superior de un módulo estándar evita que sus miembros sean

https://riptutorial.com/

109

Página 125 expuestos como macros y UDF a la aplicación host.

Sugerencias de tipo Las sugerencias de tipo están muy desaconsejadas. Existen y están documentados aquí para fines históricos y razones de compatibilidad con versiones anteriores. En su lugar, debería utilizar la sintaxis As [DataType] . Declaración de subejemplo público () Dim someInteger% '% Equivalente a "As Integer" Dim someLong & '& Equivalent to "As Long" Dim someDecimal @ '@ Equivalente a "As Currency" Dim someSingle! '! Equivalente a "Como soltero" Dim someDouble # '# Equivalente a "As Double" Atenuar someString $ '$ Equivalente a "As String" Dim someLongLong ^ '^ Equivalente a "As LongLong" en hosts VBA de 64 bits End Sub

Las sugerencias de tipo disminuyen significativamente la legibilidad del código y fomentan un legado Notación húngara https://translate.googleusercontent.com/translate_f

107/223

6/1/2021

Intitulado

que también dificulta la legibilidad: Dim strFile $ Dim iFile%

En su lugar, declare las variables más cercanas a su uso y nombre las cosas por lo que se usan, no después su tipo: Ruta tenue como cadena Controlador tenue como entero

Las sugerencias de tipo también se pueden usar en literales para imponer un tipo específico. Por defecto, un literal numérico menor que 32,768 se interpretará como un literal entero , pero con una sugerencia de tipo que puede controlar ese: Variante implícita de Dim foo ' foo = 42 & 'foo ahora es un Long foo = 42 # 'foo ahora es un Double Debug.Print TypeName (42!) 'Imprime "Single"

Las sugerencias de tipo generalmente no son necesarias en literales, porque se asignarían a una variable declarado con un tipo explícito, o convertido implícitamente al tipo apropiado cuando se pasa como parámetros. Las conversiones implícitas se pueden evitar utilizando una de las conversiones de tipo explícitas funciones: 'Llama al procedimiento DoSomething y pasa un literal 42 como Long usando una sugerencia de tipo Hacer algo 42 y 'Llama al procedimiento DoSomething y pasa un literal 42 convertido explícitamente en un Long Hacer Algo CLng (42)

https://riptutorial.com/

110

Página 126

Funciones integradas de retorno de cadenas La mayoría de las funciones integradas que manejan cadenas vienen en dos versiones: versión que devuelve una variante y una versión fuertemente tipada (que termina en $ ) que devuelve una cadena . A menos que esté asignando el valor de retorno a una variante , debe preferir la versión que devuelve un Cadena :

de lo contrario, hay una conversión implícita del valor de retorno.

Debug.Print Left (foo, 2) 'Left devuelve una variante Debug.Print Left $ (foo, 2) 'Left $ devuelve una cadena

Estas funciones son: • VBA.Conversion.Error -> VBA.Conversion.Error $ • VBA.Conversion.Hex -> VBA.Conversion.Hex $ • VBA.Conversion.Oct -> VBA.Conversion.Oct $ • • • • • • • •

VBA.Conversion.Str -> VBA.Conversion.Str $ VBA.FileSystem.CurDir -> VBA.FileSystem.CurDir $ VBA. [_ HiddenModule] .Input -> VBA. [_ HiddenModule] .Input $ VBA. [_ HiddenModule] .InputB -> VBA. [_ HiddenModule] .InputB $ VBA.Interaction.Command -> VBA.Interaction.Command $ VBA.Interaction.Environ -> VBA.Interaction.Environ $ VBA.Strings.Chr -> VBA.Strings.Chr $ VBA.Strings.ChrB -> VBA.Strings.ChrB $

• VBA.Strings.ChrW -> VBA.Strings.ChrW $ • VBA.Strings.Format -> VBA.Strings.Format $ https://translate.googleusercontent.com/translate_f

108/223

6/1/2021

Intitulado

• • • • • • •

VBA.Strings.LCase -> VBA.Strings.LCase $ VBA.Strings.Left -> VBA.Strings.Left $ VBA.Strings.LeftB -> VBA.Strings.LeftB $ VBA.Strings.LTtrim -> VBA.Strings.LTrim $ VBA.Strings.Mid -> VBA.Strings.Mid $ VBA.Strings.MidB -> VBA.Strings.MidB $ VBA.Strings.Right -> VBA.Strings.Right $

• • • • • • •

VBA.Strings.RightB -> VBA.Strings.RightB $ VBA.Strings.RTrim -> VBA.Strings.RTrim $ VBA.Strings.Space -> VBA.Strings.Space $ VBA.Strings.Str -> VBA.Strings.Str $ VBA.Strings.String -> VBA.Strings.String $ VBA.Strings.Trim -> VBA.Strings.Trim $ VBA.Strings.UCase -> VBA.Strings.UCase $

Tenga en cuenta que estos son alias de funciones , no sugerencias de tipo . La función Izquierda corresponde a la función oculta B_Var_Left , mientras que la versión Left $ corresponde a la función oculta B_Str_Left . En versiones muy tempranas de VBA, el signo $ no es un carácter permitido y el nombre de la función tenía que ser entre corchetes. En Word Basic, hubo muchas, muchas más funciones que devolvieron cadenas que terminan en $.

https://riptutorial.com/

111

Página 127

Declarar cadenas de longitud fija En VBA, las cadenas se pueden declarar con una longitud específica; se rellenan o truncan automáticamente para mantener esa longitud declarada. Sub público TwoTypesOfStrings () Dim FixedLengthString As String * 5 'declara una cadena de 5 caracteres Dim NormalString como cadena Debug.Print FixedLengthString 'Imprime "" Debug.Print NormalString

'Imprime ""

FixedLengthString = "123"

'FixedLengthString ahora es igual a "123"

NormalString = "456"

'NormalString ahora es igual a "456"

FixedLengthString = "123456"

'FixedLengthString ahora es igual a "12345"

NormalString = "456789"

'NormalString ahora es igual a "456789"

End Sub

Cuándo usar una variable estática Una variable estática declarada localmente no se destruye y no pierde su valor cuando el Sub se sale del procedimiento. Las llamadas posteriores al procedimiento no requieren reinicialización o asignación aunque es posible que desee "poner a cero" los valores recordados. Estos son particularmente útiles cuando se vincula tarde un objeto en un sub 'auxiliar' que se llama repetidamente. Fragmento 1: reutilización de unObjeto de scripting.Dictionary en muchas hojas de trabajo Opción explícita Sub principal() Dim w tan largo Para w = 1 a las hojas de trabajo. processDictionary ws: = Hojas de trabajo (w) Siguiente w End Sub

https://translate.googleusercontent.com/translate_f

109/223

6/1/2021

Intitulado Subproceso Diccionario (ws como hoja de trabajo) Dim i tan largo, rng como rango Dictado estático como objeto Si dict no es nada entonces 'inicializa y configura el objeto de diccionario Establecer dict = CreateObject ("Scripting.Dictionary") dict.CompareMode = vbTextCompare Más 'eliminar todas las entradas de diccionario preexistentes 'esto puede ser deseable o no si un solo diccionario de entradas 'de todas las hojas de trabajo es preferible dict.RemoveAll Terminara si

https://riptutorial.com/

112

Página 128

Con ws 'trabajar con un nuevo objeto de diccionario para cada hoja de trabajo 'sin construir / destruir un nuevo objeto cada vez 'o no borre el diccionario en usos posteriores y 'crea un diccionario que contenga entradas de todas las hojas de trabajo Terminar con End Sub

Fragmento 2: cree una UDF de hoja de trabajo que enlace tarde el objeto VBScript.RegExp Opción explícita Números de función Solo (str As String, _ Delimitar opcionalmente como cadena = ",") Dim n As Long, nums () As Variant Rgx estático como objeto, cmat como objeto 'con rgx como estático, solo debe crearse una vez 'esto es beneficioso cuando se llena una columna larga con esta UDF Si rgx no es nada, entonces Establecer rgx = CreateObject ("VBScript.RegExp") Más Establecer cmat = Nada Terminara si Con rgx .Global = Verdadero .MultiLine = Verdadero .Patrón = "[0-9] {1,999}" Si .Test (str) Entonces Establecer cmat = .Execute (str) 'cambiar el tamaño de la matriz nums para aceptar las coincidencias ReDim nums (recuento cmat - 1) 'rellenar la matriz nums con las coincidencias Para n = LBound (nums) a UBound (nums) nums (n) = cmat.Item (n) Siguiente n 'convierte la matriz nums en una cadena delimitada numbersOnly = Unir (nums, delim) Más numerosOnly = vbNullString Terminara si Terminar con Función final

https://translate.googleusercontent.com/translate_f

110/223

6/1/2021

Intitulado

https://riptutorial.com/

113

Página 129

Ejemplo de UDF con objeto estático llenado a través de medio millón de filas

* Tiempos transcurridos para llenar 500K filas con UDF: - con Dim rgx como objeto : 148,74 segundos - con Static rgx como objeto : 26,07 segundos

* Estos deben considerarse solo para comparación relativa. Sus propios resultados variarán según el complejidad y Alcance de las operaciones realizadas.

Recuerde que una UDF no se calcula una sola vez en la vida útil de un libro. Incluso un no volátil UDF volverá a calcular siempre que los valores dentro del rango (s) a los que hace referencia estén sujetos a cambios. Cada evento de recálculo posterior solo aumenta los beneficios de una variable declarada estáticamente. • Una variable estática está disponible durante la vida útil del módulo, no el procedimiento o la función en que fue declarado y asignado. • Las variables estáticas solo se pueden declarar localmente. • La variable estática tiene muchas de las mismas propiedades de una variable de nivel de módulo privado pero con una alcance más restringido.

Referencia relacionada: Estático (Visual Basic)

Lea Declaración de variables en línea: https://riptutorial.com/vba/topic/877/declaring-variables

https://riptutorial.com/

114

Página 130 https://translate.googleusercontent.com/translate_f

111/223

6/1/2021

Intitulado

Capítulo 21: Manejo de errores Ejemplos Evitando condiciones de error Cuando ocurre un error en tiempo de ejecución, un buen código debería manejarlo. La mejor estrategia de manejo de errores es escribir código que compruebe condiciones de error y simplemente evite ejecutar código que resulte en una Error de tiempo de ejecución. Un elemento clave para reducir los errores en tiempo de ejecución es escribir pequeños procedimientos que hagan una sola cosa . los Menos razones por las que los procedimientos tienen que fallar, más fácil es depurar el código en su conjunto.

Evitar el error de tiempo de ejecución 91 - Objeto o Con variable de bloque no establecida: Este error se generará cuando se utilice un objeto antes de que se asigne su referencia. Uno podría tener un procedimiento que recibe un parámetro de objeto: Private Sub DoSomething (destino ByVal como hoja de trabajo) Debug.Print target.Name End Sub

Si al objetivo no se le asigna una referencia, el código anterior generará un error que se puede evitar fácilmente mediante comprobar si el objeto contiene una referencia de objeto real: Private Sub DoSomething (destino ByVal como hoja de trabajo) Si el objetivo no es nada, salga de Sub Debug.Print target.Name End Sub

Si el destino no tiene asignada una referencia, la referencia no asignada nunca se usa y no hay error ocurre. Esta forma de salir anticipadamente de un procedimiento cuando uno o más parámetros no son válidos, se denomina guardia cláusula .

Evitando el error de tiempo de ejecución 9 - Subíndice fuera de rango: Este error se genera cuando se accede a una matriz fuera de sus límites. Private Sub DoSomething (índice ByVal como entero) Debug.Print ActiveWorkbook.Worksheets (índice) End Sub

Dado un índice mayor que el número de hojas de trabajo en ActiveWorkbook , el código anterior generar un error de tiempo de ejecución. Una simple cláusula de protección puede evitar que:

https://riptutorial.com/

115

Página 131

Private Sub DoSomething (índice ByVal como entero) Si index> ActiveWorkbook.Worksheets.Count Or index 2 'Se puede usar "Is" en lugar de la variable en las condiciones. MsgBox "i es mayor que 2" 'Case 2 3 MsgBox "x es mayor que 3" Caso y Exportar:

https://riptutorial.com/

143

Página 159

https://translate.googleusercontent.com/translate_f

136/223

6/1/2021

Intitulado

Asistente de exportación

https://riptutorial.com/

144

Página 160

https://translate.googleusercontent.com/translate_f

137/223

6/1/2021

Intitulado

Haga clic en Siguiente

https://riptutorial.com/

145

Página 161 la única opción preseleccionada estará disponible, así que haga clic en 'Siguiente' nuevamente:

https://translate.googleusercontent.com/translate_f

138/223

6/1/2021

Intitulado

El elemento superior ya estará preseleccionado. Haga clic en Siguiente nuevamente y elija un nombre y una ubicación para guarde el certificado exportado.

https://riptutorial.com/

146

Página 162

Haga clic en Siguiente nuevamente para guardar el certificado. Una vez que el foco se devuelve a la Consola de administración. Expanda el menú Certificados y, en el menú Autoridades de certificación raíz de confianza, seleccione Certificados .

https://translate.googleusercontent.com/translate_f

139/223

6/1/2021

https://riptutorial.com/

Intitulado

147

Página 163

Botón derecho del ratón. Seleccionar todas las tareas e importar

https://translate.googleusercontent.com/translate_f

140/223

6/1/2021

Intitulado

https://riptutorial.com/

148

Página 164

Haga clic en siguiente y guarde en la tienda Trusted Root Certification Authorities :

https://translate.googleusercontent.com/translate_f

141/223

6/1/2021

Intitulado

https://riptutorial.com/

149

Página 165 Luego Siguiente> Finalizar, ahora cierre la Consola. Si ahora usa el certificado y verifica sus propiedades, verá que es un certificado confiable y puedes usarlo para firmar tu proyecto:

Lea la seguridad de macros y la firma de proyectos / módulos VBA en línea: https://riptutorial.com/vba/topic/7733/macro-security-and-signing-of-vba-projects--modules

https://riptutorial.com/

150

Página 166

Capítulo 27: Medición de la longitud de cuerdas https://translate.googleusercontent.com/translate_f

142/223

6/1/2021

Intitulado

Observaciones La longitud de una cuerda se puede medir de dos formas: La medida de longitud más utilizada es la número de caracteres que utilizan las funciones de Len , pero VBA también puede revelar el número de bytes utilizando Funciones LenB . Un carácter de doble byte o Unicode tiene más de un byte de longitud.

Ejemplos Use la función Len para determinar el número de caracteres en una cadena Const baseString As String = "Hola mundo" Dim charLength As Long charLength = Len (baseString) 'charlength = 11

Utilice la función LenB para determinar el número de bytes en una cadena Const baseString As String = "Hola mundo" Dim byteLength tan largo byteLength = LenB (baseString) 'byteLength = 22

Prefiera `If Len (myString) = 0 Then` sobre` If myString = "" Then` Al verificar si una cadena tiene longitud cero, es una mejor práctica y más eficiente inspeccionar el longitud de la cadena en lugar de comparar la cadena con una cadena vacía. Const myString como cadena = vbNullString 'Prefiera este método al verificar si myString es una cadena de longitud cero Si Len (myString) = 0 Entonces Debug.Print "myString es de longitud cero" Terminara si 'Evite usar este método al verificar si myString es una cadena de longitud cero Si myString = vbNullString Entonces Debug.Print "myString es de longitud cero" Terminara si

Leer Medición de la longitud de cuerdas en línea: https://riptutorial.com/vba/topic/3576/measuring-thelongitud-de-cuerdas

https://riptutorial.com/

151

Página 167

Capítulo 28: Convenciones de nomenclatura Ejemplos Nombres de variables Las variables contienen datos. Nómbrelos según para qué se utilizan, no según su tipo de datos o alcance, usando un sustantivo . Si se siente obligado a numerar sus variables (por ejemplo , cosa1, cosa2, cosa3 ), entonces en su lugar, considere utilizar una estructura de datos adecuada (por ejemplo, una matriz, una colección o un diccionario ). Nombres de variables que representan un conjunto iterable de valores, por ejemplo, una matriz, una colección , una https://translate.googleusercontent.com/translate_f

143/223

6/1/2021

Intitulado

El diccionario ,

o un rango de celdas, debe estar en plural.

Algunas convenciones de nombres de VBA comunes son así:

Para variables a nivel de procedimiento : el caso de Carmel

Nombre de subejemplo público (ByVal inputValue As Long, ByRef inputVariable As Long) Procedimiento de atenuación Variable siempre que Dim someOtherVariable As String End Sub

Para variables de nivel de módulo: PascalCase

Public GlobalVariable siempre que Módulo privado Variable como cadena

Para constantes: SHOUTY_SNAKE_CASE se

usa comúnmente para diferenciar constantes de variables:

Public Const GLOBAL_CONSTANT As String = "Versión del proyecto # 1.000.000.001" Private Const MODULE_CONSTANT As String = "Algo relevante para este módulo" Sub Público SomeProcedure () Const PROCEDURE_CONSTANT Tan largo = 10 End Sub

Sin embargo, los nombres de PascalCase crean un código de aspecto más limpio y son igual de buenos, dado IntelliSense utiliza diferentes iconos para variables y constantes: https://riptutorial.com/

152

Página 168

Notación húngara Nómbrelos según para qué se utilizan, no según su tipo de datos o alcance. "La notación húngara hace que sea más fácil ver cuál es el tipo de variable" Si escribe su código, como los procedimientos, se adhiere al principio de responsabilidad única (ya que debería), nunca debería mirar una pantalla llena de declaraciones de variables en la parte superior de cualquier procedimiento; declarar las variables lo más cerca posible de su primer uso, y su tipo de datos estar siempre a la vista si los declara con un tipo explícito. El atajo Ctrl + i de VBE se puede https://translate.googleusercontent.com/translate_f

144/223

6/1/2021

Intitulado

también se usa para mostrar el tipo de una variable en una información sobre herramientas. Para qué se utiliza una variable es información mucho más útil que su tipo de datos, especialmente en un lenguaje como VBA que feliz e implícitamente convierte un tipo en otro según sea necesario. Considere iFile y strFile en este ejemplo: Función bReadFile (ByVal strFile como cadena, ByRef strData como cadena) como booleano Dim bRetVal como booleano Dim iFile como entero En caso de error, vaya a CleanFail iFile = FreeFile Abra strFile para la entrada como #iFile Entrada #iFile, strData bRetVal = Verdadero Limpiar Salida: Cerrar #iFile bReadFile = bRetVal Función de salida CleanFail: bRetVal = Falso Reanudar Limpiar Salir Función final

Comparar con: Función CanReadFile (ruta ByVal como cadena, ByRef outContent como cadena) como booleano

https://riptutorial.com/

153

Página 169

En caso de error, vaya a CleanFail Controlador tenue como entero handle = FreeFile Abrir ruta para entrada como #handle Entrada #handle, outContent Resultado atenuado como booleano resultado = Verdadero Limpiar Salida: Cerrar #handle CanReadFile = resultado Función de salida CleanFail: resultado = Falso Reanudar Limpiar Salir Función final

strData se

pasa ByRef en el ejemplo superior, pero además del hecho de que tenemos la suerte de verlo se pasa explícitamente como tal, no hay ninguna indicación de que strData sea realmente devuelto por la función. El ejemplo inferior lo nombra outContent ; esto a cabo prefijo es lo que se inventó la notación húngara para: para ayudar a aclarar para qué se utiliza una variable , en este caso para identificarla claramente como una "salida" parámetro. Esto es útil, porque IntelliSense por sí mismo no muestra ByRef , incluso cuando el parámetro es pasado explícitamente por referencia:

Lo que lleva a... https://translate.googleusercontent.com/translate_f

145/223

6/1/2021

Intitulado

Húngaro bien hecho La notación húngara originalmente no tenía nada que ver con los tipos de variables. De hecho, húngaro La notación bien hecha es realmente útil. Considere este pequeño ejemplo ( ByVal y As Integer eliminado por brevedad): Subcopia pública (iX1, iY1, iX2, iY2) End Sub

Comparar con: Subcopia pública (srcColumn, srcRow, dstColumn, dstRow) End Sub

src y dst son

prefijos de notación húngara , y transmiten información útil que no puede de lo contrario, ya se infiere de los nombres de los parámetros o IntelliSense mostrándonos el declarado tipo. https://riptutorial.com/

154

Página 170 Por supuesto, hay una mejor manera de transmitirlo todo, utilizando la abstracción adecuada y palabras reales que pueden ser pronunciado en voz alta y tiene sentido, como un ejemplo artificial: Tipo de coordenadas RowIndex tan largo ColumnIndex tan largo Tipo final Copia secundaria (origen como coordenadas, destino como coordenadas) End Sub

Nombres de procedimientos Los procedimientos hacen algo . Nómbrelos por lo que están haciendo, usando un verbo . Si nombra con precisión un procedimiento no es posible, es probable que el procedimiento esté haciendo demasiadas cosas y deba romperse en procedimientos más pequeños y especializados. Algunas convenciones de nombres de VBA comunes son así:

Para todos los procedimientos: PascalCase

Sub DoThing público () End Sub Función privada ReturnSomeValue () como [DataType] Función final

Para los procedimientos del controlador de eventos: ObjectName_EventName

Public Sub Workbook_Open () End Sub Botón secundario público1_Click () End Sub

https://translate.googleusercontent.com/translate_f

146/223

6/1/2021

Intitulado

Los controladores de eventos suelen ser nombrados automáticamente por el VBE; renombrarlos sin renombrar el objeto y / o el evento manejado romperá el código - el código se ejecutará y compilará, pero el controlador El procedimiento quedará huérfano y nunca se ejecutará. Miembros booleanos Considere una función de retorno booleano: Función bReadFile (ByVal strFile como cadena, ByRef strData como cadena) como booleano

https://riptutorial.com/

155

Página 171

Función final

Comparar con: Función CanReadFile (ruta ByVal como cadena, ByRef outContent como cadena) como booleano Función final

El prefijo Can tiene el mismo propósito que el prefijo b : identifica el valor de retorno de la función como booleano . Pero Can se lee mejor que b : Si CanReadFile (ruta, contenido) Entonces

Comparado con: Si bReadFile (strFile, strData) Entonces

Considere usar prefijos como Can , Is o Has delante de los miembros que devuelven booleanos (funciones y propiedades), pero solo cuando aporta valor. Esto se ajusta a laactual Microsoft namin g directrices . Lea las convenciones de nomenclatura en línea: https://riptutorial.com/vba/topic/1184/naming-conventions

https://translate.googleusercontent.com/translate_f

147/223

6/1/2021

Intitulado

https://riptutorial.com/

156

Página 172

Capítulo 29: Caracteres no latinos Introducción VBA puede leer y escribir cadenas en cualquier idioma o script usando Unicode . Sin embargo, hay reglas más estrictas para Tokens de identificación .

Ejemplos Texto no latino en código VBA En la celda A1 de la hoja de cálculo, tenemos el siguiente pangrama árabe: ‫ﻌﻄﺎر‬ ِ‫ﻀﺠﯿ ُﻊ ﺑِﮭﺎ ﻧَﺠﻼ َء ﻣ‬ ِ ‫ﺻﻒ ﺧَﻠﻖَ ﺧَﻮ ِد َﻛﻤِ ﺜ ِﻞ اﻟﺸ‬ َ ‫ ﯾَﺤﻈﻰ اﻟ‬- ‫َﻤﺲ إِذ ﺑَﺰَ ﻏَﺖ‬ ِ ِ VBA proporciona las funciones AscW y ChrW para trabajar con códigos de caracteres multibyte. También podemos use matrices de bytes para manipular la variable de cadena directamente: Sub NonLatinStrings () Atenuar como rango Establecer rng = Rango ("A1") Hacer hasta rng = "" Dim MyString como cadena MyString = rng.Value 'Funciones AscW Dim char como cadena char = AscW (Izquierda (MyString, 1)) Debug.Print "Primer carácter (ChrW):" & char Debug.Print "Primer carácter (binario):" & BinaryFormat (carácter, 12) 'Funciones ChrW Dim uString como cadena uString = ChrW (carácter) Debug.Print "Valor de cadena (texto):" & uString

¡Falla! Aparece como '?'

Debug.Print "Valor de cadena (AscW):" & AscW (uString) 'Usando una cadena de bytes Dim StringAsByt () como byte StringAsByt = MyString Dim i tan largo Para i = 0 a 1 Paso 2 Debug.Print "Valores de bytes (en decimal):" & _ StringAsByt (i) y "|" & StringAsByt (i + 1) Debug.Print "Valores de bytes (binarios):" & _ BinaryFormat (StringAsByt (i)) & "|" & BinaryFormat (StringAsByt (i + 1)) Siguiente yo Debug.Print "" 'Error al imprimir la cadena completa en la ventana inmediata (todos los'? ') Debug.Print "Cadena completa" & vbNewLine & rng.Value Establecer rng = rng.Offset (1)

https://riptutorial.com/

157

Página 173

Lazo End Sub

https://translate.googleusercontent.com/translate_f

148/223

6/1/2021

Intitulado

Esto produce la siguiente salida para el Letra árabe triste : Primer carácter (ChrW): 1589 Primer carácter (binario): 00011000110101 Valor de cadena (texto):? Valor de cadena (AscW): 1589 Valores de bytes (en decimal): 53 | 6 Valores de bytes (binarios): 00110101 | 00000110 Cadena entera ??? ????? ????? ??????? ??????? ??? ??????? - ????? ???????? ???? ??????? ??????? Tenga en cuenta que VBA no puede imprimir texto no latino en la ventana inmediata aunque la cadena las funciones funcionan correctamente. Esta es una limitación del IDE y no del idioma.

Identificadores no latinos y cobertura de idiomas Los identificadores de VBA (nombres de variables y funciones) pueden usar la escritura latina y también pueden usar japonés ,Corea ,Chino simplificado yEscrituras tradicionales chinas . La escritura latina extendida tiene una cobertura completa para muchos idiomas: Inglés, francés, español, alemán, italiano, bretón, catalán, danés, estonio, finlandés, islandés, Indonesio, irlandés, lojban, mapudungun, noruego, portugués, gaélico escocés, sueco, Tagalo Algunos idiomas están cubiertos solo parcialmente: Azerí, croata, checo, esperanto, húngaro, letón, lituano, polaco, rumano, serbio, Eslovaco, esloveno, turco, yoruba, galés Algunos idiomas tienen poca o ninguna cobertura: Árabe, búlgaro, cherokee, dzongkha, griego, hindi, macedonio, malayalam, mongol, Ruso, sánscrito, tailandés, tibetano, urdu, uigur Las siguientes declaraciones de variables son todas válidas: Dim Yec'hed As String 'Breton Dim «Dóna» As String 'Catalán Dim fræk As String 'danés Dim tšellomängija As String 'estonio Dim Törkylempijävongahdus As String 'finlandés Dim j'examine As String 'Francés Dim Paß As String 'Alemán Dim þjófum As String 'islandés Dim hÓighe As String 'irlandés Dim sofybakni As String 'Lojban (.o'i no funciona) Dim ñizol As String 'Mapudungun

https://riptutorial.com/

158

Página 174

Dim Vår As String 'Noruego Dim «brações» As String 'Portugués Dim d'fhàg As String 'gaélico escocés

Tenga en cuenta que en el IDE de VBA, un solo apóstrofo dentro de un nombre de variable no convierte la línea en un comentario (como lo hace en Stack Overflow). Además, los idiomas que utilizan dos ángulos para indicar una cita «» pueden utilizar los de variable los nombres describen el hecho de que las comillas de tipo "" no lo son. Leer caracteres no latinos en línea: https://riptutorial.com/vba/topic/10555/non-latin-characters

https://translate.googleusercontent.com/translate_f

149/223

6/1/2021

Intitulado

https://riptutorial.com/

159

Página 175

Capítulo 30: VBA orientado a objetos Ejemplos Abstracción Los niveles de abstracción ayudan a determinar cuándo dividir las cosas. La abstracción se logra implementando funcionalidad con código cada vez más detallado. La entrada El punto de una macro debe ser un pequeño procedimiento con un alto nivel de abstracción que facilite la capte de un vistazo lo que está pasando: Sub público DoSomething () Con el nuevo SomeForm Establecer .Model = CreateViewModel .Mostrar vbModal Si .IsCancelled, salga de Sub ProcessUserData .Model Terminar con End Sub

https://translate.googleusercontent.com/translate_f

150/223

6/1/2021

Intitulado

El procedimiento DoSomething tiene un alto nivel de abstracción : podemos decir que está mostrando un formulario y creando algún modelo y pasando ese objeto a algún procedimiento ProcessUserData que sepa qué que ver con eso - cómo se crea el modelo es el trabajo de otro procedimiento: Función privada CreateViewModel () como ISomeModel Resultado atenuado como ISomeModel Establecer resultado = SomeModel.Create (Ahora, Environ $ ("UserName")) result.AvailableItems = GetAvailableItems Establecer CreateViewModel = resultado Función final

La función CreateViewModel solo es responsable de crear alguna instancia de ISomeModel . Parte de eso La responsabilidad es adquirir una variedad de elementos disponibles ; cómo se adquieren estos elementos es una detalles de implementación que se resumen detrás del procedimiento GetAvailableItems : Función privada GetAvailableItems () como variante GetAvailableItems = DataSheet.Names ("AvailableItems"). RefersToRange Función final

Aquí el procedimiento es la lectura de los valores disponibles de un rango con nombre en una Hoja de datos de hoja de cálculo. También podría leerlos de una base de datos, o los valores podrían estar codificados: es un detalles de implementación que no son motivo de preocupación para ninguno de los niveles de abstracción más altos.

Encapsulamiento La encapsulación oculta los detalles de implementación del código del cliente.

https://riptutorial.com/

160

Página 176 los El ejemplo de manejo de QueryClose demuestra la encapsulación: el formulario tiene un control de casilla de verificación, pero su código de cliente no funciona con él directamente: la casilla de verificación es un detalle de implementación , lo que El código del cliente necesita saber si la configuración está habilitada o no. Cuando el valor de la casilla de verificación cambia, el controlador asigna un miembro de campo privado: TView de tipo privado IsCancelled como booleano SomeOtherSetting como booleano 'otras propiedades omitidas por brevedad Tipo final Privado esto como TView '... Sub privado SomeOtherSettingInput_Change () this.SomeOtherSetting = CBool (SomeOtherSettingInput.Value) End Sub

Y cuando el código del cliente quiere leer ese valor, no necesita preocuparse por una casilla de verificación: en su lugar, simplemente usa la propiedad SomeOtherSetting : Propiedad pública Obtener SomeOtherSetting () como booleano SomeOtherSetting = this.SomeOtherSetting Propiedad final

La propiedad SomeOtherSetting encapsula el estado de la casilla de verificación; el código del cliente no necesita saber que hay una casilla de verificación involucrada, solo que hay una configuración con un valor booleano. por encapsulado el valor booleano , hemos agregado una capa de abstracción alrededor de la casilla de verificación.

Usar interfaces para imponer la inmutabilidad https://translate.googleusercontent.com/translate_f

151/223

6/1/2021

Intitulado

Llevemos eso un paso más allá encapsulando el modelo del formulario en un módulo de clase dedicado. Pero si hicimos una propiedad pública para el nombre de usuario y la marca de tiempo , tendríamos que exponer la propiedad Let accesores, haciendo que las propiedades sean mutables, y no queremos que el código del cliente tenga la capacidad de cambie estos valores una vez establecidos. La función CreateViewModel en el ejemplo de Abstraction devuelve una clase ISomeModel : esa es nuestra interfaz , y se parece a esto: Opción explícita Propiedad pública Obtener marca de tiempo () como fecha Propiedad final Propiedad pública Obtener UserName () como cadena Propiedad final Propiedad pública Obtener AvailableItems () como variante Propiedad final Propiedad pública Let AvailableItems (valor ByRef como variante)

https://riptutorial.com/

161

Página 177

Propiedad final Propiedad pública Obtener SomeSetting () como cadena Propiedad final Propiedad pública Let SomeSetting (valor ByVal como cadena) Propiedad final Propiedad pública Obtener SomeOtherSetting () como booleano Propiedad final Propiedad pública Let SomeOtherSetting (valor ByVal como booleano) Propiedad final

Observe que las propiedades de marca de tiempo y nombre de usuario solo exponen un descriptor de acceso de obtención de propiedad . Ahora el SomeModel la clase puede implementar esa interfaz: Opción explícita Implementa ISomeModel Modelo privado de tipo Marca de tiempo como fecha Nombre de usuario como cadena SomeSetting como cadena SomeOtherSetting como booleano AvailableItems como variante Tipo final Privado esto como TModel Propiedad privada Obtenga ISomeModel_Timestamp () como fecha ISomeModel_Timestamp = this.Timestamp Propiedad final Propiedad privada Obtenga ISomeModel_UserName () como cadena ISomeModel_UserName = this.UserName Propiedad final Propiedad privada Obtenga ISomeModel_AvailableItems () como variante ISomeModel_AvailableItems = this.AvailableItems Propiedad final Propiedad privada Let ISomeModel_AvailableItems (valor ByRef como variante) this.AvailableItems = valor Propiedad final Propiedad privada Obtenga ISomeModel_SomeSetting () como cadena ISomeModel_SomeSetting = this.SomeSetting Propiedad final

https://translate.googleusercontent.com/translate_f

152/223

6/1/2021

Intitulado Propiedad privada Let ISomeModel_SomeSetting (valor ByVal como cadena) this.SomeSetting = valor Propiedad final Propiedad privada Obtenga ISomeModel_SomeOtherSetting () como booleano ISomeModel_SomeOtherSetting = this.SomeOtherSetting Propiedad final Propiedad privada Let ISomeModel_SomeOtherSetting (valor ByVal como booleano) this.SomeOtherSetting = valor Propiedad final

https://riptutorial.com/

162

Página 178

Propiedad pública Obtener marca de tiempo () como fecha Timestamp = this.Timestamp Propiedad final Propiedad pública Let Timestamp (valor ByVal como fecha) this.Timestamp = valor Propiedad final Propiedad pública Obtener UserName () como cadena Nombre de usuario = this.UserName Propiedad final Propiedad pública Let UserName (valor ByVal como cadena) this.UserName = valor Propiedad final Propiedad pública Obtener AvailableItems () como variante AvailableItems = this.AvailableItems Propiedad final Propiedad pública Let AvailableItems (valor ByRef como variante) this.AvailableItems = valor Propiedad final Propiedad pública Obtener SomeSetting () como cadena SomeSetting = this.SomeSetting Propiedad final Propiedad pública Let SomeSetting (valor ByVal como cadena) this.SomeSetting = valor Propiedad final Propiedad pública Obtener SomeOtherSetting () como booleano SomeOtherSetting = this.SomeOtherSetting Propiedad final Propiedad pública Let SomeOtherSetting (valor ByVal como booleano) this.SomeOtherSetting = valor Propiedad final

Los miembros de la interfaz son todos privados y todos los miembros de la interfaz deben implementarse para el código para compilar. Los miembros públicos no forman parte de la interfaz y, por lo tanto, no expuestos al código escrito en la interfaz ISomeModel .

Usando un método de fábrica para simular un constructor Usando un Atributo VB_PredeclaredId , podemos hacer que laclase SomeModel tenga una instancia predeterminada , y escriba una función que funcione como un miembro de nivel de tipo ( compartido en VB.NET, estático en C #) que el cliente el código puede llamar sin necesidad de crear primero una instancia, como hicimos aquí: Función privada CreateViewModel () como ISomeModel Resultado atenuado como ISomeModel Establecer resultado = SomeModel.Create (Ahora, Environ $ ("UserName")) result.AvailableItems = GetAvailableItems Establecer CreateViewModel = resultado

https://translate.googleusercontent.com/translate_f

153/223

6/1/2021

Intitulado

https://riptutorial.com/

163

Página 179

Función final

Este método de fábrica asigna los valores de propiedad que son de solo lectura cuando se accede desde el Interfaz ISomeModel , aquí Timestamp y UserName : Función pública Crear (ByVal pTimeStamp como fecha, ByVal pUserName como cadena) como ISomeModel Con nuevo SomeModel .Timestamp = pTimeStamp .UserName = pUserName Establecer Crear = .Self Terminar con Función final Propiedad pública Get Self () As ISomeModel Establecer yo = Yo Propiedad final

Y ahora podemos codificar contra la interfaz ISomeModel , que expone Timestamp y UserName como propiedades de solo lectura que nunca se pueden reasignar (siempre que el código esté escrito en interfaz).

Polimorfismo El polimorfismo es la capacidad de presentar la misma interfaz para diferentes implementaciones subyacentes. La capacidad de implementar interfaces permite desacoplar completamente la lógica de la aplicación de la UI, o de la base de datos, o de esta o aquella hoja de trabajo. Supongamos que tiene una interfaz ISomeView que implementa el formulario en sí: Opción explícita Propiedad pública Obtener IsCancelled () como booleano Propiedad final Propiedad pública Obtener modelo () como ISomeModel Propiedad final Modelo de conjunto de propiedades públicas (valor ByVal como ISomeModel) Propiedad final Sub Show público () End Sub

El código subyacente del formulario podría verse así: Opción explícita Implementa ISomeView TView de tipo privado IsCancelled como booleano Modelo como ISomeModel

https://riptutorial.com/

164

Página 180

Tipo final Privado esto como TView

https://translate.googleusercontent.com/translate_f

154/223

6/1/2021

Intitulado Propiedad privada Obtenga ISomeView_IsCancelled () como booleano ISomeView_IsCancelled = this.IsCancelled Propiedad final Propiedad privada Obtenga ISomeView_Model () como ISomeModel Establecer ISomeView_Model = this.Model Propiedad final Conjunto de propiedades privadas ISomeView_Model (valor de ByVal como ISomeModel) Establezca this.Model = value Propiedad final Sub privado ISomeView_Show () Me.Show vbModal End Sub Sub privado SomeOtherSettingInput_Change () this.Model.SomeOtherSetting = CBool (SomeOtherSettingInput.Value) End Sub '... otros controladores de eventos ... Sub privado OkButton_Click () Me.Hide End Sub Sub privado CancelButton_Click () this.IsCancelled = True Me.Hide End Sub Private Sub UserForm_QueryClose (Cancelar como entero, CloseMode como entero) Si CloseMode = VbQueryClose.vbFormControlMenu, entonces Cancelar = Verdadero this.IsCancelled = True Me.Hide Terminara si End Sub

Pero entonces, nada prohíbe la creación de otro módulo de clase que implemente la interfaz ISomeView sin ser un formulario de usuario , esto podría ser una clase SomeViewMock : Opción explícita Implementa ISomeView TView de tipo privado IsCancelled como booleano Modelo como ISomeModel Tipo final Privado esto como TView Propiedad pública Obtener IsCancelled () como booleano IsCancelled = this.IsCancelled Propiedad final Propiedad pública Let IsCancelled (valor ByVal como booleano) this.IsCancelled = valor

https://riptutorial.com/

165

Página 181

Propiedad final Propiedad privada Obtenga ISomeView_IsCancelled () como booleano ISomeView_IsCancelled = this.IsCancelled Propiedad final Propiedad privada Obtenga ISomeView_Model () como ISomeModel Establecer ISomeView_Model = this.Model Propiedad final Conjunto de propiedades privadas ISomeView_Model (valor de ByVal como ISomeModel) Establezca this.Model = value Propiedad final

https://translate.googleusercontent.com/translate_f

155/223

6/1/2021

Intitulado Sub privado ISomeView_Show () 'hacer nada End Sub

Y ahora podemos cambiar el código que funciona con un UserForm y hacerlo funcionar desde ISomeView interfaz, por ejemplo, dándole el formulario como parámetro en lugar de instanciarlo: Public Sub DoSomething (vista ByVal como ISomeView) Con vista Establecer .Model = CreateViewModel .Mostrar Si .IsCancelled, salga de Sub ProcessUserData .Model Terminar con End Sub

Debido a que el HacerAlgo método depende de una interfaz (es decir, una abstracción ) y no un hormigón clase (por ejemplo, un UserForm específico ), podemos escribir una prueba unitaria automatizada que asegure que ProcessUserData no SomeViewMock ,

se ejecuta cuando view.IsCancelled es True , al hacer que nuestra prueba cree un estableciendo su propiedad IsCancelled en True y pasándola a DoSomething .

El código comprobable depende de abstracciones Se pueden escribir pruebas unitarias en VBA, hay complementos que incluso lo integran en el IDE. Pero cuando el código está estrechamente vinculado con una hoja de trabajo, una base de datos, un formulario o el sistema de archivos, luego, la prueba unitaria comienza a requerir una hoja de trabajo, base de datos, formulario o sistema de archivos real, y estos Las dependencias son nuevos puntos de falla fuera de control que el código comprobable debe aislar, de modo que la unidad las pruebas no requieren una hoja de trabajo, una base de datos, un formulario o un sistema de archivos reales. Escribiendo código contra interfaces, de una manera que permita que el código de prueba inyecte stub / mock implementaciones (como el ejemplo anterior de SomeViewMock ), puede escribir pruebas en un "control entorno ", y simular lo que sucede cuando cada una de las 42 posibles permutaciones de las interacciones del usuario en los datos del formulario, sin siquiera mostrar un formulario y hacer clic manualmente en un control de formulario. Lea VBA orientado a objetos en línea: https://riptutorial.com/vba/topic/5357/object-oriented-vba

https://riptutorial.com/

166

Página 182

Capítulo 31: Operadores Observaciones Los operadores se evalúan en el siguiente orden: • • • • •

Operadores matemáticos Operadores bit a bit Operadores de concatenación Operadores de comparación Operadores logicos

Los operadores con precedencia coincidente se evalúan de izquierda a derecha. El orden predeterminado puede ser anulado mediante el uso de paréntesis ( y ) para agrupar expresiones.

Ejemplos https://translate.googleusercontent.com/translate_f

156/223

6/1/2021

Intitulado

Operadores matemáticos Listados en orden de precedencia: Nombre del token

Exponenciación

^

Descripción Devuelve el resultado de elevar el operando de la izquierda a la potencia de el operando de la derecha. Tenga en cuenta que el valor devuelto por exponenciación es siempre un doble , independientemente de los tipos de valor estar dividido. Cualquier coerción del resultado en un tipo de variable toma lugar después de realizar el cálculo. Devuelve el resultado de dividir el operando de la izquierda por el de la derecha. operando de mano. Tenga en cuenta que el valor devuelto por la división es siempre un

/

División 1

Doble ,

*

Multiplicación 1

Devuelve el producto de 2 operandos.

\

Entero División

Devuelve el resultado entero de dividir el operando de la izquierda por el operando de la derecha después de redondear ambos lados con .5 redondeo abajo. Cualquier resto de la división se ignora. Si la mano derecha operando (el divisor) es 0 , un error en tiempo de ejecución 11: la división por cero resultado. Tenga en cuenta que esto es después de realizar todo el redondeo: expresiones como 3 \ 0.4 también resultarán en una división por cero error.

Modificación

Modulo

Devuelve el resto entero de dividir el operando de la izquierda por

independientemente de los tipos de valor que se dividan. Cualquier coacción de el resultado en un tipo de variable tiene lugar después de que el cálculo es realizado.

https://riptutorial.com/

167

Página 183 Nombre del token

Descripción el operando de la derecha. El operando de cada lado se redondea a un número entero antes de la división, con .5 redondeando hacia abajo. Por ejemplo, tanto 8.6 Mod 3 como 12 Mod 2.6 dan como resultado 0 . Si el operando de la derecha (el divisor) es 0 , un error en tiempo de ejecución 11: resultará una división por cero. Tenga en cuenta que esto es después de realizar todo el redondeo: expresiones como como 3 Mod 0.4 también resultará en una división por error cero.

-

Resta 2

Devuelve el resultado de restar el operando de la derecha del operando de la izquierda.

+

Adición 2

Devuelve la suma de 2 operandos. Tenga en cuenta que este token también se trata como un operador de concatenación cuando se aplica a una cadena . Ver Operadores de concatenación .

1 Se considera que la multiplicación 2 La

y la división tienen la misma precedencia.

suma y la resta se tratan como si tuvieran la misma precedencia.

Operadores de concatenación VBA admite 2 operadores de concatenación diferentes, + y &, y ambos realizan exactamente lo mismo función cuando se utiliza con Cuerda tipos - de la derecha de cadena se añade al final de la izquierda cuerda de mano . Si el operador & se usa con un tipo de variable que no sea String , se convierte implícitamente en String antes de ser concatenados.

https://translate.googleusercontent.com/translate_f

157/223

6/1/2021

Intitulado

Tenga en cuenta que el operador de concatenación + es una sobrecarga del operador de suma + . El comportamiento de + está determinado por el tipos de variables de los operandos y precedencia de los tipos de operadores. Si ambos los operandos se escriben como String o Variant con un subtipo de String , están concatenados: Subejemplo público () Atenuar a la izquierda como cadena Dim right As String izquierda = "5" derecha = "5" Debug.Print left + right 'Imprime "55" End Sub

Si cualquiera de los lados es de tipo numérico y el otro lado es una cadena que se puede convertir en un número, la precedencia de tipos de los operadores matemáticos hace que el operador sea tratado como la suma operador y se añaden los valores numéricos: Subejemplo público () Atenuar a la izquierda como variante Dim right As String

https://riptutorial.com/

168

Página 184

izquierda = 5 derecha = "5" Debug.Print izquierda + derecha 'Imprime 10 End Sub

Este comportamiento puede provocar errores sutiles y difíciles de depurar, especialmente si se utilizan tipos de variantes , por lo que solo se debe usar el operador & para la concatenación.

Operadores de comparación Nombre del token

=

Igual a

Descripción Devuelve True si los operandos de la izquierda y la derecha son igual. Tenga en cuenta que esto es una sobrecarga de la tarea operador.

No igual a

Devuelve True si los operandos de la izquierda y la derecha son no es igual.

>

Mas grande que

Devuelve True si el operando de la izquierda es mayor que el operando de la derecha.


=

Mayor que o igual

Devuelve True si el si el operando de la izquierda es mayor que o igual al operando de la derecha.

b> c

... puede ser leído en algunos contextos como una prueba de si b es entre una y c . En VBA, esto evalúa como sigue: a = 2: b = 1: c = 0 expr = a> b> c expr = (2> 1)> 0 expr = Verdadero> 0 expr = -1> 0 'CInt (verdadero) = -1 expr = Falso

Cualquier operador de comparación que no sea Se usa con un Objeto como operando se ejecutará en el valor de retorno del objeto s'miembro predeterminado . Si el objeto no tiene un miembro predeterminado, el la comparación dará como resultado un error 438 en tiempo de ejecución: "El objeto no admite su propiedad o método". Si el objeto no está inicializado, la comparación dará como resultado un error en tiempo de ejecución 91 - "Variable de objeto o Con variable de bloque no establecida ". Si el literal Nothing se usa con cualquier operador de comparación que no sea Is , resultará en una compilación error - "Uso no válido del objeto". Si el miembro predeterminado del objeto es otro objeto , VBA llamará continuamente al miembro predeterminado de cada valor de retorno sucesivo hasta que se devuelve un tipo primitivo o se genera un error. Por ejemplo, suponga que SomeClass tiene un miembro predeterminado de Value , que es una instancia de ChildClass con un valor predeterminado miembro de ChildValue . La comparación... Establecer x = New SomeClass Depurar Imprimir x> 42

... será evaluado como: Establecer x = New SomeClass Debug.Print x.Value.ChildValue> 42

Si alguno de los operandos es de tipo numérico y el otro operando es una cadena o una variante del subtipo Cadena , se realizará una comparación numérica. En este caso, si la Cadena no se puede convertir en un número, un Error de tiempo de ejecución 13 - "No coinciden los tipos" como resultado de la comparación. Si ambos operandos son una Cadena o una Variante del subtipo Cadena , se realizará una comparación de cadenas basado en el Opción Comparar configuración del módulo de código. Estas comparaciones se realizan en un carácter por carácter. Tenga en cuenta que la representación de caracteres de una cadena que contiene un https://translate.googleusercontent.com/translate_f

159/223

6/1/2021

Intitulado

número no es lo mismo que una comparación de los valores numéricos:

https://riptutorial.com/

170

Página 186

Subejemplo público () Atenuar a la izquierda como variante Dim a la derecha como variante izquierda = "42" derecha = "5" Depurar Imprimir izquierda> derecha

'Imprime falso

Debug.Print Val (izquierda)> Val (derecha) 'Prints True End Sub

Por esta razón, asegúrese de que las variables String o Variant se conviertan en números antes de realizar comparaciones numéricas de desigualdad sobre ellos. Si un operando es una fecha , se realizará una comparación numérica del valor Double subyacente si el otro operando es numérico o se puede convertir a un tipo numérico. Si el otro operando es una Cadena o una Variante del subtipo Cadena que se puede convertir a una Fecha usando el configuración regional actual, la cadena se convertirá en una fecha . Si no se puede convertir a una fecha en la configuración regional actual, Error de tiempo de ejecución 13 - "No coinciden los tipos" como resultado de la comparación.

Se debe tener cuidado al hacer comparaciones entre valores dobles o simples yBooleanos. A diferencia de otros tipos numéricos, no se puede suponer que los valores distintos de cero sean verdaderos debido al comportamiento de VBA de promover el tipo de datos de una comparación que involucra un número de punto flotante a Double : Subejemplo público () Prueba de atenuación como doble Prueba = 42

Debug.Print CBool (prueba)

'Imprime True.

'Verdadero se promueve a doble: la prueba no se convierte en booleano Debug.Print Test = True

'Imprime falso

'Con elencos explícitos: Debug.Print CBool (Prueba) = True 'Imprime True Debug.Print CDbl (-1) = CDbl (True) 'Imprime True End Sub

Operadores bit a bit \ lógicos Todos los operadores lógicos en VBA se pueden considerar como "anulaciones" de los operadores bit a bit del mismo nombre. Técnicamente, siempre se tratan como operadores bit a bit. Toda la comparación los operadores en VBA devuelven un Booleano , que siempre no tendrá ninguno de sus bits establecido ( Falso ) o todos sus bits establecidos ( Verdadero ). Pero tratará un valor con cualquier bit establecido como Verdadero . Esto significa que el resultado de la convertir el resultado bit a bit de una expresión en un booleano (ver Operadores de comparación) siempre será lo mismo que tratarlo como una expresión lógica. Asignar el resultado de una expresión usando uno de estos operadores dará el resultado bit a bit. Nota que en las tablas de verdad a continuación, 0 es equivalente a Falso y 1 es equivalente a Verdadero .

Y

Devuelve Verdadero si las expresiones en ambos lados se evalúan como Verdadero . https://riptutorial.com/

171

Página 187 Operando de la mano izquierda Resultado del operando de la mano derecha https://translate.googleusercontent.com/translate_f

160/223

6/1/2021

Intitulado

0

0

0

0

1

0

1

0

0

1

1

1

O

Devuelve Verdadero si cualquiera de los lados de la expresión se evalúa como Verdadero . Operando de la mano izquierda Resultado del operando de la mano derecha 0

0

0

0

1

1

1

0

1

1

1

1

No

Devuelve True si la expresión se evalúa como False y False si la expresión se evalúa como True . Resultado del operando de la derecha 0

1

1

0

No es

el único operando sin operando a la izquierda. El Editor de Visual Basic automáticamente simplificar expresiones con un argumento a la izquierda. Si escribe ... Debug.Print x No y

... el VBE cambiará la línea a: Debug.Print No x

Se harán simplificaciones similares a cualquier expresión que contenga un operando de la izquierda (incluyendo expresiones) para Not .

Xor

https://riptutorial.com/

172

Página 188 También conocido como "exclusivo o". Devuelve True si ambas expresiones evalúan resultados diferentes. Operando de la mano izquierda Resultado del operando de la mano derecha 0

0

0

0

1

1

1

0

1

https://translate.googleusercontent.com/translate_f

161/223

6/1/2021

Intitulado

1

1

0

Tenga en cuenta que aunque el operador Xor se puede utilizar como un operador lógico, no hay absolutamente ningún razón para hacerlo, ya que da el mismo resultado que el operador de comparación .

Eqv

También conocido como "equivalencia". Devuelve True cuando ambas expresiones evalúan el mismo resultado. Operando de la mano izquierda Resultado del operando de la mano derecha 0

0

1

0

1

0

1

0

0

1

1

1

Tenga en cuenta que la función Eqv se usa muy raramente ya que x Eqv y es equivalente a la mucho más legible No (x Xor y) .

Diablillo

También conocido como "implicación". Devuelve True si ambos operandos son iguales o si el segundo operando es Cierto .

Operando de la mano izquierda Resultado del operando de la mano derecha 0

0

1

0

1

1

1

0

0

1

1

1

Tenga en cuenta que la función Imp se utiliza muy raramente. Una buena regla general es que si no puede explicar qué https://riptutorial.com/

173

Página 189 significa que debes usar otra construcción. Leer operadores en línea: https://riptutorial.com/vba/topic/5813/operators

https://translate.googleusercontent.com/translate_f

162/223

6/1/2021

Intitulado

https://riptutorial.com/

174

Página 190

Capítulo 32: Pasando argumentos por Ref o ByVal Introducción Los modificadores ByRef y ByVal son parte de la firma de un procedimiento e indican cómo es un argumento. pasado a un procedimiento. En VBA se pasa un parámetro ByRef a menos que se especifique lo contrario (es decir, ByRef está implícito si está ausente). Nota En muchos otros lenguajes de programación (incluido VB.NET), los parámetros se pasan implícitamente por valor si no se especifica ningún modificador: considere especificar los modificadores ByRef explícitamente para evitar posibles confusión.

Observaciones Pasando matrices Las matrices deben pasarse por referencia. Este código se compila, pero genera el error 424 en tiempo de ejecución "Objeto Necesario": Subprueba pública () Matriz DoSomething (1, 2, 3) End Sub Private Sub DoSomething (ByVal foo como variante)

https://translate.googleusercontent.com/translate_f

163/223

6/1/2021

Intitulado foo.Añadir 42 End Sub

Este código no compila: Private Sub DoSomething (ByVal foo () As Variant) 'ByVal es ilegal para matrices foo.Añadir 42 End Sub

Ejemplos Pasar variables simples ByRef y ByVal Pasar ByRef o ByVal indica si el valor real de un argumento se pasa al CalledProcedure por

el CallingProcedure , o si una referencia (llamado un puntero en alguna otra languages) se pasa al CalledProcedure . Si se pasa un argumento ByRef , la dirección de memoria del argumento se pasa al CalledProcedure y

cualquier modificación a ese parámetro por el CalledProcedure se realiza en el valor en el CallingProcedure . https://riptutorial.com/

175

Página 191 Si se pasa un argumento ByVal , el valor real, no una referencia a la variable, se pasa al CalledProcedure .

Un ejemplo simple ilustrará esto claramente: Sub CalledProcedure (ByRef X As Long, ByVal Y As Long) X = 321 Y = 654 End Sub Sub CallingProcedure () Dim A tan largo Dim B tan largo A = 123 B = 456 Debug.Print "ANTES DE LLAMAR => A:" & CStr (A), "B:" & CStr (B) '' Resultado: ANTES DE LLAMAR => A: 123 B: 456 Procedimiento llamado X: = A, Y: = B Debug.Print "AFTER CALL = A:" & CStr (A), "B:" & CStr (B) '' Resultado: DESPUÉS DE LLAMADA => A: 321 B: 456 End Sub

Otro ejemplo: Sub principal() Dim IntVarByVal como entero Dim IntVarByRef como entero IntVarByVal = 5 IntVarByRef = 10 SubChangeArguments IntVarByVal, IntVarByRef '5 entra como una "copia". 10 entra como referencia Debug.Print "IntVarByVal:" & IntVarByVal 'imprime 5 (sin cambios realizados por SubChangeArguments) Debug.Print "IntVarByRef:" & IntVarByRef 'imprime 99 (la variable se cambió en SubChangeArguments) End Sub Sub SubChangeArguments (ByVal ParameterByVal como entero, ByRef ParameterByRef como entero) ParameterByVal = ParameterByVal + 2 '5 + 2 = 7 (cambiado solo dentro de este Sub) ParameterByRef = ParameterByRef + 89 '10 + 89 = 99 (cambia el propio IntVarByRef - en el Sub principal)

https://translate.googleusercontent.com/translate_f

164/223

6/1/2021

Intitulado End Sub

ByRef

Modificador predeterminado Si no se especifica ningún modificador para un parámetro, ese parámetro se pasa implícitamente por referencia. Public Sub DoSomething1 (foo As Long)

https://riptutorial.com/

176

Página 192

End Sub

Public Sub DoSomething2 (ByRef foo As Long) End Sub

El parámetro foo se pasa ByRef en DoSomething1 y DoSomething2 . ¡Cuidado! Si vienes a VBA con experiencia en otros idiomas, esto es muy probablemente el comportamiento exactamente opuesto al que está acostumbrado. En muchos otros lenguajes de programación (incluido VB.NET), el modificador implícito / predeterminado pasa parámetros por valor.

Pasando por referencia • Cuando se pasa un valor ByRef , el procedimiento recibe una referencia al valor. Subprueba pública () Dim foo tan largo foo = 42 Hacer algo foo Debug.Print foo End Sub Sub privado DoSomething (ByRef foo As Long) foo = foo * 2 End Sub

Llamar a las salidas 84 del procedimiento de prueba anterior . DoSomething recibe foo y recibe un referencia al valor y, por lo tanto, funciona con la misma dirección de memoria que la persona que llama. • Cuando se pasa una referencia ByRef , el procedimiento recibe una referencia al puntero. Subprueba pública () Colección Dim foo As Set foo = Nueva colección Hacer algo foo Debug.Print foo.Count End Sub Private Sub DoSomething (ByRef foo As Collection) foo.Añadir 42 Establecer foo = Nada End Sub

El código anterior plantea error 91 en tiempo de ejecución , porque la persona que llama está llamando almiembro Count de un objeto que ya no existe, porque DoSomething recibió una referencia al objeto puntero y lo asignó a Nothing antes de regresar.

https://translate.googleusercontent.com/translate_f

165/223

6/1/2021

Intitulado

Forzar ByVal en el sitio de la llamada https://riptutorial.com/

177

Página 193 Usando paréntesis en el sitio de la llamada, puede anular ByRef y forzar que se pase un argumento ByVal :

Subprueba pública () Dim foo tan largo foo = 42 Hacer algo (foo) Debug.Print foo End Sub Sub privado DoSomething (ByRef foo As Long) foo = foo * 2 End Sub

El código anterior genera 42, independientemente de si ByRef se especifica implícita o explícitamente. ¡Cuidado! Debido a esto, el uso de paréntesis extraños en llamadas a procedimientos puede introducir errores fácilmente. Preste atención al espacio en blanco entre el nombre del procedimiento y la lista de argumentos: bar = DoSomething (foo) 'llamada a la función, sin espacios en blanco; parens son parte de la lista de argumentos Llamada al procedimiento DoSomething (foo) ', observe los espacios en blanco; parens NO son parte de argumentos lista La llamada al procedimiento DoSomething foo 'no obliga al parámetro foo a ser ByVal

ByVal Pasando por valor • Cuando se pasa un valor ByVal , el procedimiento recibe una copia del valor. Subprueba pública () Dim foo tan largo foo = 42 Hacer algo foo Debug.Print foo End Sub Sub privado DoSomething (ByVal foo As Long) foo = foo * 2 End Sub

Llamar a las salidas 42 del procedimiento de prueba anterior . DoSomething recibe foo y recibe una copia de el valor. La copia se multiplica por 2 y luego se descarta cuando finaliza el procedimiento; la la copia de la persona que llama nunca fue alterada. • Cuando se pasa una referencia ByVal , el procedimiento recibe una copia del puntero. Subprueba pública () Colección Dim foo As Set foo = Nueva colección Hacer algo foo Debug.Print foo.Count

https://riptutorial.com/

178

Página 194

https://translate.googleusercontent.com/translate_f

166/223

6/1/2021

Intitulado End Sub Private Sub DoSomething (ByVal foo As Collection) foo.Añadir 42 Establecer foo = Nada End Sub

Llamar a las salidas del procedimiento de prueba anteriores 1. DoSomething recibe foo y recibe una copia de el puntero al objeto Collection . Porque la variable de objeto foo en los puntos de alcance de prueba al mismo objeto, agregar un elemento en DoSomething agrega el elemento al mismo objeto. Porque es una copia del puntero, establecer su referencia en Nothing no afecta la propia copia de la persona que llama. Lea Pasando argumentos ByRef o ByVal en línea: https://riptutorial.com/vba/topic/7363/passingargumentos-byref-or-byval

https://riptutorial.com/

179

Página 195

Capítulo 33: Llamadas a procedimientos Sintaxis • IdentifierName [ argumentos ] • Nombre de identificador de llamada [ (argumentos) ] • [Let | Set] expresión = IdentifierName [ (argumentos) ] https://translate.googleusercontent.com/translate_f

167/223

6/1/2021

Intitulado

• [Let | Set] IdentifierName [ (argumentos) ] = expresión

Parámetros Parámetro

Información

IdentifierName El nombre del procedimiento a llamar. argumentos

Una lista de argumentos separados por comas que se pasarán al procedimiento.

Observaciones Las dos primeras sintaxis son para llamar a procedimientos Sub ; observe que la primera sintaxis no implica paréntesis. Ver Esto es confuso. ¿Por qué no usar siempre paréntesis? para una explicación detallada del diferencias entre las dos primeras sintaxis. La tercera sintaxis es para llamar a los procedimientos de obtención de funciones y propiedades ; cuando hay parámetros, los paréntesis son siempre obligatorios. La palabra clave Let es opcional al asignar un valor , pero la palabra clave Set es necesaria al asignar una referencia . La cuarta sintaxis es para llamar a los procedimientos Property Let y Property Set ; la expresión de la derecha El lado de la mano de la asignación se pasa al parámetro de valor de la propiedad.

Ejemplos Sintaxis de llamada implícita Nombre del procedimiento Nombre de procedimiento argumento1, argumento2

Llame a un procedimiento por su nombre sin paréntesis.

Caso extremo https://riptutorial.com/

180

Página 196 La palabra clave Call solo es necesaria en un caso extremo: Llamar a DoSomething: DoSomethingElse

DoSomething y DoSomethingElse son

procedimientos que se llaman. Si se eliminó la palabra clave Call , entonces DoSomething se analizaría como una etiqueta de línea en lugar de una llamada a procedimiento, que se rompería el código: DoSomething: DoSomethingElse 'solo DoSomethingElse se ejecutará

Valores devueltos Para recuperar el resultado de una llamada a procedimiento (por ejemplo, procedimientos de obtención de función o propiedad ), coloque la llamada en el lado derecho de una tarea: resultado = nombreProcedimiento resultado = nombreProcedimiento (argumento1, argumento2)

https://translate.googleusercontent.com/translate_f

168/223

6/1/2021

Intitulado

Los paréntesis deben estar presentes si hay parámetros. Si el procedimiento no tiene parámetros, el los paréntesis son redundantes.

Esto es confuso. ¿Por qué no usar siempre paréntesis? Los paréntesis se utilizan para encerrar los argumentos de las llamadas a funciones . Usándolos para llamadas a procedimientos puede causar problemas inesperados. Debido a que pueden introducir errores, tanto en tiempo de ejecución pasando un valor posiblemente no intencionado al procedimiento, y en tiempo de compilación simplemente siendo sintaxis inválida.

Tiempo de ejecución Los paréntesis redundantes pueden introducir errores. Dado un procedimiento que toma una referencia de objeto como un parámetro ... Sub DoSomething (destino ByRef como rango) End Sub

... y llamado entre paréntesis: DoSomething (Application.ActiveCell) 'genera un error en tiempo de ejecución

Esto generará un error de tiempo de ejecución "Objeto requerido" # 424. Otros errores son posibles en otros circunstancias: aquí la referencia del objeto Application.ActiveCell Range se está evaluando y pasado por valor independientemente de la firma del procedimiento que especifica que el objetivo se pasaría ByRef .

El valor real pasado ByVal a DoSomething en el fragmento anterior es

Application.ActiveCell.Value .

https://riptutorial.com/

181

Página 197 Los paréntesis obligan a VBA a evaluar el valor de la expresión entre corchetes y pasar el resultado ByVal al

procedimiento llamado. Cuando el tipo de resultado evaluado no coincide con el tipo esperado y no se puede convertir implícitamente, se genera un error de tiempo de ejecución.

Tiempo de compilación Este código no se podrá compilar: MsgBox ("Código no válido", vbCritical)

Porque la expresión ("¡Código no válido!", VbCritical) no se puede evaluar como un valor. Esto compilaría y funcionaría: MsgBox ("¡Código no válido!"), (VbCritical)

Pero definitivamente se vería tonto. Evite los paréntesis redundantes.

Sintaxis de llamada explícita Nombre de procedimiento de llamada Llamar NombreProcedimiento (argumento1, argumento2)

La sintaxis de llamada explícita requiere la palabra clave Call y paréntesis alrededor de la lista de argumentos; los paréntesis son redundantes si no hay parámetros. Esta sintaxis se volvió obsoleta cuando el https://translate.googleusercontent.com/translate_f

169/223

6/1/2021

Intitulado

Se agregó una sintaxis de llamada implícita más moderna a VB.

Argumentos opcionales Algunos procedimientos tienen argumentos opcionales. Los argumentos opcionales siempre vienen después de required argumentos, pero el procedimiento se puede llamar sin ellos. Por ejemplo, si la función, NombreProcedimiento tuviera dos argumentos obligatorios ( argumento1 , argumento2 ),

y un argumento opcional, optArgument3 , se podría llamar al menos de cuatro formas:

'Sin argumento opcional resultado = NombreProcedimiento ("A", "B") 'Con argumento opcional resultado = NombreProcedimiento ("A", "B", "C") 'Usar argumentos con nombre (permite un orden diferente) resultado = NombreProcedimiento (optArgumento3: = "C", argumento1: = "A", argumento2: = "B") 'Mezcla de argumentos con nombre y sin nombre resultado = nombreProcedimiento ("A", "B", optArgument3: = "C")

La estructura del encabezado de la función que se llama aquí se vería así:

https://riptutorial.com/

182

Página 198

Función Nombre del procedimiento (argumento1 como cadena, argumento2 como cadena, opcional optArgument3 como String) como cadena

La palabra clave opcional indica que este argumento se puede omitir. Como se mencionó antes, cualquier Los argumentos opcionales introducidos en el encabezado deben aparecer al final, después de cualquier requisito argumentos. También puede proporcionar un valor predeterminado para el argumento en el caso de que no se pase un valor al función: Función Nombre del procedimiento (argumento1 como cadena, argumento2 como cadena, opcional optArgument3 como String = "C") como cadena

En esta función, si no se proporciona el argumento para c , su valor será por defecto "C" . Si se proporciona un valor entonces esto anulará el valor predeterminado. Lea las llamadas de procedimiento en línea: https://riptutorial.com/vba/topic/1179/procedure-calls

https://translate.googleusercontent.com/translate_f

170/223

6/1/2021

Intitulado

https://riptutorial.com/

183

Página 199

Capítulo 34: Lectura de archivos de 2GB + en binario en VBA y hashes de archivos Introducción Hay una forma fácil de leer archivos en binario dentro de VBA, sin embargo, tiene una restricción de 2GB (2,147,483,647 bytes - máximo de tipo de datos Long). A medida que la tecnología evoluciona, este límite de 2 GB se violado. por ejemplo, una imagen ISO del disco DVD de instalación del sistema operativo. Microsoft proporciona una forma para superar esto a través de la API de Windows de bajo nivel y aquí hay una copia de seguridad. También demuestre (Leer parte) para calcular File Hashes sin un programa externo como fciv.exe de Microsoft.

Observaciones MÉTODOS PARA LA CLASE DE MICROSOFT Nombre del método

Descripción

Esta abierto

Devuelve un booleano para indicar si el archivo está abierto.

OpenFile ( sFileNam e Como cuerda)

Abre el archivo especificado por el argumento sFileName.

Cerrar el archivo

Cierra el archivo abierto actualmente.

ReadBytes ( ByteCount tan largo)

Lee ByteCount bytes y los devuelve en una matriz de bytes Variant y mueve el puntero.

WriteBytes ( DataBytes () como byte)

Escribe el contenido de la matriz de bytes en la posición actual del archivo. y mueve el puntero.

Enjuagar

Obliga a Windows a vaciar la caché de escritura. Mueve el puntero del archivo a la posición designada desde el principio

SeekAbsolute ( HighPos tan largo, LowPos tan largo)

del archivo. Aunque VBA trata los DWORDS como valores firmados, el API los trata como sin firmar. Haga que el argumento de orden superior no sea cero para superar los 4 GB. El DWORD de orden inferior será negativo para valores entre 2GB y 4GB.

Mueve el puntero del archivo hasta +/- 2GB desde la ubicación actual. usted SeekRelative ( Desplazamiento https://translate.googleusercontent.com/translate_f

171/223

6/1/2021

Intitulado

puede reescribir este método para permitir compensaciones superiores a 2 GB por convertir un desplazamiento con signo de 64 bits en dos valores de 32 bits.

Tanto tiempo)

https://riptutorial.com/

184

Página 200

PROPIEDADES DE LA CLASE POR MICROSOFT Propiedad

Descripción

FileHandle

El identificador de archivo para el archivo abierto actualmente. Esto no es compatible con el archivo VBA manejas.

Nombre del archivo El nombre del archivo abierto actualmente. AutoFlush Establece / indica si WriteBytes llamará automáticamente al método Flush.

MÓDULO NORMAL Función

Notas

GetFileHash ( sFile As String, uBlockSize As Doble, sHashType como Cuerda)

Simplemente agregue la ruta completa para aplicar el hash, Blocksize para usar (número de bytes) y el tipo de Hash que se utilizará, uno de los constantes: HashTypeMD5 , HashTypeSHA1 , HashTypeSHA256 , HashTypeSHA384 , HashTypeSHA512 . Esto fue diseñado para ser tan genérico como sea posible.

Debe anular / comentar uFileSize como doble en consecuencia. He probado MD5 y SHA1.

Ejemplos Esto tiene que estar en un módulo de clase, los ejemplos más adelante se denominarán "aleatorios" 'Cómo buscar más allá del límite de archivos de 2GB de VBA Fuente: https://support.microsoft.com/en-us/kb/189981 (Archivado) 'Esto debe estar en un módulo de clase Opción explícita Enumeración pública W32F_Errors W32F_UNKNOWN_ERROR = 45600 W32F_FILE_ALREADY_OPEN W32F_PROBLEM_OPENING_FILE W32F_FILE_ALREADY_CLOSED W32F_Problem_seeking End Enum Private Const W32F_SOURCE = "Objeto Win32File" Const privada GENERIC_WRITE = & H40000000 Const privada GENERIC_READ = & H80000000 Const privada FILE_ATTRIBUTE_NORMAL = & H80 Const privada CREATE_ALWAYS = 2 Const privada OPEN_ALWAYS = 4 Const privada INVALID_HANDLE_VALUE = -1

https://riptutorial.com/

185

Página 201 https://translate.googleusercontent.com/translate_f

172/223

6/1/2021

Intitulado Const privada FILE_BEGIN = 0, FILE_CURRENT = 1, FILE_END = 2 Const privada FORMAT_MESSAGE_FROM_SYSTEM = & H1000 Función de declaración privada FormatMessage Lib "kernel32" Alias "FormatMessageA" (_ ByVal dwFlags As Long, _ lpSource siempre que, _ ByVal dwMessageId tan largo, _ ByVal dwLanguageId As Long, _ ByVal lpBuffer como cadena, _ ByVal nSize As Long, _ Argumentos como cualquiera) siempre que Función de declaración privada ReadFile Lib "kernel32" (_ ByVal hFile tan largo, _ lpBuffer como cualquiera, _ ByVal nNumberOfBytesToRead tan largo, _ lpNumberOfBytesRead As Long, _ ByVal lp Superpuesto siempre que) Función de declaración privada CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Función de declaración privada WriteFile Lib "kernel32" (_ ByVal hFile tan largo, _ lpBuffer como cualquiera, _ ByVal nNumberOfBytesToWrite como largo, _ lpNumberOfBytesWritten As Long, _ ByVal lp Superpuesto siempre que) Función de declaración privada CreateFile Lib "kernel32" Alias "CreateFileA" (_ ByVal lpFileName como cadena, _ ByVal dwDesiredAccess siempre que, _ ByVal dwShareMode Tan largo, _ ByVal lpSecurityAttributes siempre que, _ ByVal dwCreationDisposition As Long, _ ByVal dwFlagsAndAttributes As Long, _ ByVal hTemplateFile As Long) As Long Función de declaración privada SetFilePointer Lib "kernel32" (_ ByVal hFile tan largo, _ ByVal lDistanceToMove tan largo, _ lpDistanceToMoveHigh tan largo, _ ByVal dwMoveMethod As Long) As Long Función de declaración privada FlushFileBuffers Lib "kernel32" (ByVal hFile As Long) As Long HFile privado tan largo, sFName como cadena, fAutoFlush como booleano Propiedad pública Obtener FileHandle () tan largo Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si FileHandle = hFile Propiedad final Propiedad pública Obtener FileName () como cadena Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si FileName = sFName Propiedad final

https://riptutorial.com/

186

Página 202

Propiedad pública Obtener IsOpen () como booleano IsOpen = hFile INVALID_HANDLE_VALUE Propiedad final Propiedad pública Obtener AutoFlush () como booleano Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si AutoFlush = fAutoFlush Propiedad final

https://translate.googleusercontent.com/translate_f

173/223

6/1/2021

Intitulado Propiedad pública Let AutoFlush (ByVal NewVal como booleano) Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si fAutoFlush = NewVal Propiedad final Public Sub OpenFile (ByVal sFileName como cadena) Si hFile INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_OPEN, sFName Terminara si hFile = CreateFile (sFileName, GENERIC_WRITE o GENERIC_READ, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0) Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_PROBLEM_OPENING_FILE, sFileName Terminara si sFName = sFileName End Sub Public Sub CloseFile () Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si CloseHandle hFile sFName = "" fAutoFlush = Falso hFile = INVALID_HANDLE_VALUE End Sub Función pública ReadBytes (ByVal ByteCount tan largo) como variante Dim BytesRead tan largo, bytes () como byte Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si ReDim Bytes (0 a ByteCount - 1) Como Byte ReadFile hFile, Bytes (0), ByteCount, BytesRead, 0 ReadBytes = Bytes Función final Public Sub WriteBytes (DataBytes () como byte) Dim fSuccess tan largo, BytesToWrite tan largo, BytesWritten tan largo Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si BytesToWrite = UBound (DataBytes) - LBound (DataBytes) + 1 fSuccess = WriteFile (hFile, DataBytes (LBound (DataBytes)), BytesToWrite, BytesWritten, 0) Si fAutoFlush, entonces enjuague End Sub

https://riptutorial.com/

187

Página 203

Descarga secundaria pública () Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si FlushFileBuffers hFile End Sub Public Sub SeekAbsolute (ByVal HighPos como largo, ByVal LowPos como largo) Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si LowPos = SetFilePointer (hFile, LowPos, HighPos, FILE_BEGIN) End Sub Public Sub SeekRelative (ByVal Offset As Long) Dim TempLow tan largo, TempErr tan largo Si hFile = INVALID_HANDLE_VALUE Entonces RaiseError W32F_FILE_ALREADY_CLOSED Terminara si TempLow = SetFilePointer (hFile, Offset, ByVal 0 &, FILE_CURRENT) Si TempLow = -1 entonces TempErr = Err.LastDllError

https://translate.googleusercontent.com/translate_f

174/223

6/1/2021

Intitulado Si TempErr entonces RaiseError W32F_Problem_seeking, "Error" & TempErr & "." & vbCrLf y CStr (TempErr) Terminara si Terminara si End Sub Private Sub Class_Initialize () hFile = INVALID_HANDLE_VALUE End Sub Subclase privada_Terminate () Si hFile INVALID_HANDLE_VALUE, entonces CloseHandle hFile End Sub Private Sub RaiseError (ByVal ErrorCode como W32F_Errors, sExtra opcional) Dim Win32Err tan largo, Win32Text como cadena Win32Err = Err.LastDllError Si Win32Err entonces Win32Text = vbCrLf & "Error" & Win32Err & vbCrLf & _ DecodeAPIErrors (Win32Err) Terminara si Seleccionar código de error de caso Caso W32F_FILE_ALREADY_OPEN Err.Raise W32F_FILE_ALREADY_OPEN, W32F_SOURCE, "El archivo '" & sExtra & "' es ya abierto ". & Win32Text Caso W32F_PROBLEM_OPENING_FILE Err.Raise W32F_PROBLEM_OPENING_FILE, W32F_SOURCE, "Error al abrir" & sExtra & "'." & Win32Text Caso W32F_FILE_ALREADY_CLOSED Err.Raise W32F_FILE_ALREADY_CLOSED, W32F_SOURCE, "No hay archivo abierto". Caso W32F_Problem_seeking Err.Raise W32F_Problem_seeking, W32F_SOURCE, "Error de búsqueda". & vbCrLf & sExtra Caso otro Err.Raise W32F_UNKNOWN_ERROR, W32F_SOURCE, "Error desconocido". & Win32Text Finalizar Seleccionar End Sub Función privada DecodeAPIErrors (ByVal ErrorCode tan largo) como cadena Dim sMessage como cadena, MessageLength tan largo

https://riptutorial.com/

188

Página 204

sMessage = Espacio $ (256) MessageLength = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, 0 &, ErrorCode, 0 &, sMessage, 256 &, 0 &) Si MessageLength> 0 entonces DecodeAPIErrors = Izquierda (sMessage, MessageLength) Más DecodeAPIErrors = "Error desconocido". Terminara si Función final

Código para calcular el hash de archivo en un módulo estándar Private Const HashTypeMD5 As String = "MD5" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.md5cryptoserviceprovider (v = frente a 110) .aspx Private Const HashTypeSHA1 As String = "SHA1" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.sha1cryptoserviceprovider (v = frente a 110) .aspx Private Const HashTypeSHA256 As String = "SHA256" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.sha256cryptoserviceprovider (v = frente a 110) .aspx Private Const HashTypeSHA384 As String = "SHA384" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.sha384cryptoserviceprovider (v = frente a 110) .aspx Private Const HashTypeSHA512 As String = "SHA512" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.sha512cryptoserviceprovider (v = frente a 110) .aspx Private uFileSize As Double 'Comente si no está probando el rendimiento con FileHashes () Sub FileHashes () Dim tStart As Date, tFinish As Date, sHash como cadena, aTestFiles como variante, oTestFile como Variante, aBlockSizes como variante, oBlockSize como variante Atenuar BLOCKSIZE como doble 'Esto realiza pruebas de rendimiento en diferentes tamaños de archivo y tamaños de bloque aBlockSizes = Array ("2 ^ 12-1", "2 ^ 13-1", "2 ^ 14-1", "2 ^ 15-1", "2 ^ 16-1", "2 ^ 17-1 "," 2 ^ 18-1 ",

https://translate.googleusercontent.com/translate_f

175/223

6/1/2021

Intitulado "2 ^ 19-1", "2 ^ 20-1", "2 ^ 21-1", "2 ^ 22-1", "2 ^ 23-1", "2 ^ 24-1", "2 ^ 25-1 "," 2 ^ 26-1 ") aTestFiles = Array ("C: \ ISO \ clonezilla-live-2.2.2-37-amd64.iso", "C: \ ISO \ HPIP201.2014_0902.29.iso", "C: \ ISO \ SW_DVD5_Windows_Vista_Business_W32_32BIT_English.ISO", "C: \ ISO \ Win10_1607_English_x64.iso", "C: \ ISO \ SW_DVD9_Windows_Svr_Std_and_DataCtr_2012_R2_64Bit_English.ISO") Debug.Print "Archivos de prueba:" & Join (aTestFiles, "|") Debug.Print "BlockSizes:" & Join (aBlockSizes, "|") Para cada oTestFile en aTestFiles Debug.Print oTestFile Para cada oBlockSize en aBlockSizes BLOCKSIZE = Evaluar (oBlockSize) tStart = Ahora sHash = GetFileHash (CStr (oTestFile), BLOCKSIZE, HashTypeMD5) tFinish = Ahora Debug.Print sHash, uFileSize, Format (tFinish - tStart, "hh: mm: ss"), oBlockSize & " (" & TAMAÑO DE BLOQUE & ")" próximo próximo End Sub Función privada GetFileHash (ByVal sFile como cadena, ByVal uBlockSize como doble, ByVal sHashType como cadena) como cadena Dim oFSO As Object '"Scripting.FileSystemObject" Dim oCSP As Object 'Uno de los "CryptoServiceProvider" Dim oRnd As Random 'La clase "Random" de Microsoft, debe estar en el mismo archivo Dim uBytesRead como doble, uBytesToRead como doble, bDone como booleano

https://riptutorial.com/

189

Página 205

Dim aBlock () As Byte, aBytes As Variant 'Arrays para almacenar bytes Dim aHash () como byte, sHash como cadena, i tan largo 'Dim uFileSize As Double' Anula el comentario si GetFileHash () se va a utilizar individualmente Establecer oRnd = New Random 'Class de Microsoft: Random Establecer oFSO = CreateObject ("Scripting.FileSystemObject") Establezca oCSP = CreateObject ("System.Security.Cryptography." & SHashType & "CryptoServiceProvider") Si oFSO es nada o oRnd es nada o oCSP es nada, entonces MsgBox "No se pueden crear uno o más objetos obligatorios" Ir a limpieza Terminara si uFileSize = oFSO.GetFile (sFile) .Size 'FILELEN () tiene 2GB como máximo. uBytesRead = 0 bDone = Falso sHash = String (oCSP.HashSize / 4, "0") 'Cada hexadecimal tiene 4 bits Application.ScreenUpdating = Falso 'Procesar el archivo en trozos de uBlockSize o menos Si uFileSize = 0 entonces ReDim aBlock (0) oCSP.TransformFinalBlock aBlock, 0, 0 bDone = Verdadero Más Con oRnd .OpenFile sFile Hacer Si uBytesRead + uBlockSize 15) + 2) = Hex (aHash (i)) próximo Terminara si Application.ScreenUpdating = True ' Limpiar oCSP.Clear Limpiar:

https://riptutorial.com/

190

Página 206

Establecer oFSO = Nada Establecer oRnd = Nada Establecer oCSP = Nada GetFileHash = sHash Función final

La salida es bastante interesante, mis archivos de prueba indican que BLOCKSIZE = 131071 (2 ^ 17-1) ofrece el mejor rendimiento general con Office 2010 de 32 bits en Windows 7 x64, el siguiente mejor es 2 ^ 16-1 (65535) . Nota 2 ^ 27-1 produce Memoria insuficiente . Tamaño del archivo (bytes)

Nombre del archivo

146,800,640

clonezilla-live-2.2.2-37-amd64.iso

798,210,048

HPIP201.2014_0902.29.iso

2,073,016,320

SW_DVD5_Windows_Vista_Business_W32_32BIT_English.ISO

4.380.387.328

Win10_1607_English_x64.iso

5.400.115.200

SW_DVD9_Windows_Svr_Std_and_DataCtr_2012_R2_64Bit_English.ISO

Calcular todos los archivos hash desde una carpeta raíz Otra variación del código anterior le brinda más rendimiento cuando desea obtener hash códigos de todos los archivos de una carpeta raíz, incluidas todas las subcarpetas.

Ejemplo de hoja de trabajo:

Código Opción explícita Private Const HashTypeMD5 As String = "MD5" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.md5cryptoserviceprovider (v = frente a 110) .aspx Private Const HashTypeSHA1 As String = "SHA1" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.sha1cryptoserviceprovider (v = frente a 110) .aspx Private Const HashTypeSHA256 As String = "SHA256" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.sha256cryptoserviceprovider (v = frente a 110) .aspx Private Const HashTypeSHA384 As String = "SHA384" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.sha384cryptoserviceprovider (v = frente a 110) .aspx

https://translate.googleusercontent.com/translate_f

177/223

6/1/2021

Intitulado Private Const HashTypeSHA512 As String = "SHA512" 'https://msdn.microsoft.com/enus / library / system.security.cryptography.sha512cryptoserviceprovider (v = frente a 110) .aspx Const privada BLOCKSIZE como doble = 131071 '2 ^ 17-1

https://riptutorial.com/

191

Página 207

OFSO privado como objeto OCSP privado como objeto Private ornd As Random 'Requiere la clase de Microsoft https://support.microsoft.com/ennosotros / kb / 189981 Private sHashType como cadena SRootFDR privado como cadena Privado oRng como rango UFileCount privado como doble Sub AllFileHashes () 'El botón Active-X llama a esto Atenuar como hoja de trabajo '| A: FileHash | B: Tamaño de archivo | C: FileName | D: FilaName y Path | E: Archivo último Hora de modificación | F: El tiempo requerido para calcular tiene código (segundos) Con este libro de trabajo 'Borrar todas las entradas antiguas en todas las hojas de trabajo Para cada oWS en .Worksheets Establecer oRng = Intersecar (oWS.UsedRange, oWS.UsedRange.Offset (2)) Si no oRng no es nada, entonces oRng.ClearContents próximo Con .hojas de trabajo (1) sHashType = Trim (.Range ("A1"). Valor) 'Rango (A1) sRootFDR = Trim (.Range ("C1"). Value) 'Range (C1) Columna B para el tamaño del archivo Si Len (sHashType) = 0 o Len (sRootFDR) = 0, salga de Sub Set oRng = .Range ("A3") 'Primera entrada en la primera página Terminar con Terminar con uFileCount = 0 Si oRnd no es nada, entonces establezca oRnd = New Random 'Class de Microsoft: Random Si oFSO no es nada, establezca oFSO = CreateObject ("Scripting.FileSystemObject") 'Solo para obtener FileSize correcto Si oCSP no es nada, establezca oCSP = CreateObject ("System.Security.Cryptography." & sHashType y "CryptoServiceProvider") ProcessFolder oFSO.GetFolder (sRootFDR) Application.StatusBar = False Application.ScreenUpdating = True oCSP.Clear Establecer oCSP = Nada Establecer oRng = Nada Establecer oFSO = Nada Establecer oRnd = Nada Debug.Print "Recuento total de archivos:" & uFileCount End Sub Carpeta de subproceso privada (ByRef oFDR como objeto) Dim oFile como objeto, oSubFDR como objeto, sHash como cadena, dStart como fecha, dFinish como fecha Application.ScreenUpdating = Falso Para cada oFile en oFDR. uFileCount = uFileCount + 1 Application.StatusBar = uFileCount & ":" & Derecha (oFile.Path, 255 - Len (uFileCount) 2) oCSP.Initialize 'Reinicializar el CryptoServiceProvider dStart = Ahora sHash = GetFileHash (oFile, BLOCKSIZE, sHashType) dFinish = Ahora Con oRng .Value = sHash .Offset (0, 1) .Value = oFile.Size 'Tamaño del archivo en bytes

https://riptutorial.com/

192

Página 208 https://translate.googleusercontent.com/translate_f

178/223

6/1/2021

Intitulado

.Offset (0, 2) .Value = oFile.Name 'Nombre de archivo con extensión .Offset (0, 3) .Value = oFile.Path 'Nombre de archivo completo y ruta .Offset (0, 4) .Value = FileDateTime (oFile.Path) 'Última modificación de fecha y hora de archivo .Offset (0, 5) .Value = dFinish - dStart 'Tiempo requerido para calcular el código hash Terminar con Si oRng.Row = Rows.Count Entonces 'Se alcanzó el número máximo de filas, comience en la siguiente hoja Si oRng.Worksheet.Index + 1> ThisWorksheets.Worksheets.Count Then MsgBox "Se han utilizado todas las filas de todas las hojas de trabajo, cree más hojas" Fin Terminara si Establecer oRng = ThisWorkbook.Sheets (oRng.Worksheet.Index + 1) .Range ("A3") oRng.Worksheet.Activar Más 'Mover a la siguiente fila de lo contrario Establecer oRng = oRng.Offset (1) Terminara si próximo 'Application.StatusBar = False Application.ScreenUpdating = True oRng.Activar Para cada oSubFDR en oFDR. ProcessFolder oSubFDR próximo End Sub Función privada GetFileHash (ByVal sFile como cadena, ByVal uBlockSize como doble, ByVal sHashType como cadena) como cadena Dim uBytesRead como doble, uBytesToRead como doble, bDone como booleano Dim aBlock () As Byte, aBytes As Variant 'Arrays para almacenar bytes Dim aHash () como byte, sHash como cadena, i tan largo, oTmp como variante Dim uFileSize As Double 'Un-Comment si GetFileHash () se va a utilizar individualmente Si oRnd no es nada, entonces establezca oRnd = New Random 'Class de Microsoft: Random Si oFSO no es nada, establezca oFSO = CreateObject ("Scripting.FileSystemObject") 'Solo para obtener FileSize correcto Si oCSP no es nada, establezca oCSP = CreateObject ("System.Security.Cryptography." & sHashType y "CryptoServiceProvider") Si oFSO es nada o oRnd es nada o oCSP es nada, entonces MsgBox "No se pueden crear uno o más objetos obligatorios" Función de salida Terminara si uFileSize = oFSO.GetFile (sFile) .Size 'FILELEN () tiene 2GB como máximo uBytesRead = 0 bDone = Falso sHash = String (oCSP.HashSize / 4, "0") 'Cada hexadecimal tiene 4 bits 'Procesar el archivo en trozos de uBlockSize o menos Si uFileSize = 0 entonces ReDim aBlock (0) oCSP.TransformFinalBlock aBlock, 0, 0 bDone = Verdadero Más Con oRnd En caso de error, GoTo CannotOpenFile .OpenFile sFile Hacer Si uBytesRead + uBlockSize