TL;DR — Un
Propertyconvierte un campo de una clase en una puerta. Desde el lado del que llama,emp.Salary = 65000parece una variable normal, pero detrás de esa asignación se ejecuta tu código —así que puedes validar, calcular o rechazar la escritura—.Property Getes la puerta de lectura,Property Letrecibe un valor yProperty Setrecibe un objeto. ConfundirLetySetes el error número uno; dejar fueraLeta propósito es como haces un campo de solo lectura.
' --- Dentro de un class module (clsEmployee) ---
Private mSalary As Currency ' el campo de respaldo, oculto del exterior
Public Property Get Salary() As Currency ' puerta de LECTURA
Salary = mSalary
End Property
Public Property Let Salary(ByVal value As Currency) ' puerta de ESCRITURA-de-un-valor
If value < 0 Then Err.Raise 5, , "Salary cannot be negative"
mSalary = value ' validado antes de guardar
End Property
' --- El uso se lee exactamente como un campo normal ---
' emp.Salary = 65000 -> ejecuta Property Let (valida, guarda)
' Debug.Print emp.Salary -> ejecuta Property Get (devuelve mSalary)
' emp.Salary = -100 -> lanza "Salary cannot be negative"
Un class module puede exponer sus datos como simples
variables Public —y a veces esa es la decisión correcta—. Pero la razón por la que las
clases se sienten más sólidas que una bolsa de campos públicos son los procedimientos
Property: son el enganche donde decides qué le está permitido hacer al mundo exterior
con cada campo.
Lo que aprenderás
- El modelo mental — una puerta delante de un campo, no una variable en crudo
- Por qué un
Propertygana a una simple variablePublic Get,LetySet— y la única distinción con la que todo el mundo tropieza- El patrón del campo de respaldo que hace que todo funcione
- Cómo hacer una propiedad de solo lectura (y por qué eso es una ventaja)
- Cuándo una simple variable
Publices la elección honesta
El modelo mental: una puerta delante de un campo
Un Property es una puerta delante de un campo. Para cualquiera que use tu objeto se
ve idéntica a una variable normal —escribe emp.Salary = 65000 y lee x = emp.Salary—,
pero cada uno de esos toques ejecuta un pequeño procedimiento que escribiste tú. La
lectura ejecuta Property Get; la escritura ejecuta Property Let (para valores) o
Property Set (para objetos).
Esa indirección es justo la clave. Como tu código se sienta en la puerta, puedes comprobar el valor antes de guardarlo, calcular un valor que no se guarda en absoluto, o sencillamente no dar una puerta de escritura para que el campo pase a ser de solo lectura. El que llama no tiene por qué enterarse —la sintaxis es la misma en cualquier caso.
Por qué un Property gana a una simple variable Public
Un campo Public es un agujero directo al interior de tu objeto: cualquiera puede
escribir lo que sea, cuando sea, sin ninguna comprobación. emp.Age = -5 funciona.
emp.Id = 999 sobrescribe una identidad que se suponía permanente. No hay ningún sitio
donde poner una regla, porque no hay código entre el que llama y el campo.
Un Property te da ese sitio. El fallo que evita es la escritura mala y silenciosa —la
edad negativa, el salario puesto a un texto que después revienta un cálculo, el id
«único» reasignado sin más—. Con un Property Let, la escritura ilegal se caza en el
momento en que ocurre, con un mensaje claro, en lugar de asomar tres procedimientos más
tarde como un resultado equivocado y misterioso.
Get, Let y Set: la única distinción con la que todo el mundo tropieza
Hay tres procedimientos de propiedad, y la división entre los dos de escritura es el clásico tropiezo de VBA:
| Procedimiento | Dirección | Recibe / devuelve | Se usa para |
|---|---|---|---|
Property Get |
Lectura | Devuelve un valor o un objeto | Leer cualquier propiedad |
Property Let |
Escritura | Recibe un valor (Long, String, Date, Currency…) | Escribir una propiedad de valor |
Property Set |
Escritura | Recibe un objeto (Range, instancia de clase…) | Escribir una propiedad de objeto |
La regla es la misma que gobierna la asignación corriente en VBA:
los valores usan Let, los objetos usan Set. Si una propiedad guarda un Range y
le escribes un Property Let, asignar emp.HomeCell = Range("A1") falla, porque asignar
un objeto necesita Set —y VBA busca un Property Set que no encuentra—. Empareja el
procedimiento con la clase de cosa que guarda el campo:
Private mRange As Range
Public Property Get HomeCell() As Range
Set HomeCell = mRange ' ojo: Set, porque devolvemos un objeto
End Property
Public Property Set HomeCell(ByVal r As Range) ' Set, no Let — es un objeto
Set mRange = r
End Property
' Uso: Set emp.HomeCell = Range("A1")
Fíjate en que incluso dentro de Property Get, devolver un objeto usa Set HomeCell = .... La distinción Let/Set sigue a la clase de dato, en todas partes.
El patrón del campo de respaldo
Las propiedades casi siempre vienen en pareja envolviendo un campo oculto. El campo es
Private (el prefijo m es la convención para «member», miembro) y el mundo llega a él
solo a través de las puertas:
Private mName As String ' campo de respaldo oculto
Public Property Get Name() As String
Name = mName
End Property
Public Property Let Name(ByVal value As String)
mName = Trim$(value) ' normaliza a la entrada
End Property
Esta es la forma que hace real el encapsulamiento: los datos viven en una sola variable
Private, y cada lectura y escritura pasa por código que controlas tú. Cambia más
adelante cómo se guarda un nombre —recortado, en mayúsculas, validado contra una lista— y
cambias un solo Property Let, no cada sitio que lo llama.
Cómo hacer una propiedad de solo lectura (y por qué eso es una ventaja)
Deja fuera el Property Let y el campo pasa a ser de solo lectura desde fuera: la
clase puede fijar el campo de respaldo internamente, pero los que llaman solo pueden
leerlo.
Private mId As Long
Public Property Get Id() As Long ' solo Get — sin Let
Id = mId
End Property
Friend Sub AssignId(ByVal newId As Long) ' la clase lo fija internamente
mId = newId
End Sub
' emp.Id -> funciona (lectura)
' emp.Id = 42 -> error de compilación: No se puede asignar a una propiedad de solo lectura
Ese error de compilación no es un obstáculo —es la garantía—. Una propiedad de solo lectura es como expresas «este valor se fija una vez y no se edita nunca», y el compilador te lo hace cumplir. La misma técnica te da propiedades calculadas que no tienen ningún campo de respaldo:
Public Property Get FullName() As String
FullName = mFirst & " " & mLast ' derivado, no se guarda nada
End Property
Cuándo una simple variable Public es la elección honesta
Aquí está el criterio que separa el buen VBA del código repetido por inercia: no todos
los campos necesitan un Property. Si un campo no necesita nunca validación, no
necesita nunca calcularse y está bien leerlo y escribirlo libremente, entonces una
variable Public dice exactamente eso —y envolverlo en una pareja Get/Let de mero
paso que no hace más que copiar mX de acá para allá añade ruido, no seguridad—.
Así que: recurre a un Property cuando tengas un motivo —validación, un id de solo
lectura, un valor calculado, un campo de objeto que necesita Set—. Para un valor simple
y sin restricciones, una variable Public es la elección honesta y legible. Añade la
puerta cuando necesites la puerta; no construyas puertas alrededor de campos abiertos.
Cómo ayuda ExcelMaster
Las reglas de las propiedades son pequeñas pero implacables: Let para valores, Set
para objetos, un Let ausente para solo lectura, un campo de respaldo Private detrás
de cada pareja. Empareja mal Let/Set y no compilará; equivoca el encapsulamiento y tu
campo «protegido» queda de par en par.
ExcelMaster escribe
toda la forma por ti. Describe el objeto —«un Employee cuyo salario no pueda ser negativo,
con un id de solo lectura y un nombre completo calculado»— y genera los campos de
respaldo Private, el Property Let que valida, el Property Set consciente de los
objetos donde haga falta, y las propiedades de solo lectura con solo Get, todo
emparejado correctamente. Consigues un encapsulamiento como es debido sin memorizar qué
palabra clave va con qué clase de campo.
Preguntas frecuentes
¿Qué es un Property en VBA?
Un Property es un procedimiento en un class module que
controla el acceso a un campo. Property Get se ejecuta cuando el campo se lee, y
Property Let (para valores) o Property Set (para objetos) se ejecuta cuando se
escribe. Para el que llama parece una variable normal —emp.Salary = 65000—, pero tu
código se ejecuta detrás de la asignación, así que puedes validar, calcular o hacer el
campo de solo lectura.
¿Cuál es la diferencia entre Property Let y Property Set?
Property Let recibe un valor —un Long, String, Date, Currency, etc.—. Property Set recibe un objeto —un Range, una instancia de clase o cualquier tipo de
referencia—. Es la misma regla que la asignación corriente: los valores usan = (vía
Let), los objetos usan Set (vía Set). Usar Let para una propiedad de objeto, o
Set para un valor, es un error de compilación o de tiempo de ejecución.
¿Cómo hago una propiedad de solo lectura en VBA?
Escribe un Property Get pero ningún Property Let (ni Set). Los que llaman pueden
entonces leer el valor pero no asignarle nada —un intento de escritura da el error de
compilación «No se puede asignar a una propiedad de solo lectura»—. La propia clase sí
puede cambiar el campo de respaldo internamente. Esto es ideal para valores de identidad
que se fijan una sola vez, o para propiedades calculadas como un nombre completo derivado
de otros campos.
¿Por qué usar un Property en lugar de una variable Public?
Una variable Public se puede escribir con cualquier valor, en cualquier momento, sin
ninguna comprobación. Un Property te da un sitio donde validar la entrada, calcular un
valor, hacer un campo de solo lectura o cambiar más adelante cómo se guardan los datos sin
tocar a quienes lo llaman. Usa un Property cuando tengas un motivo así; para un valor
simple y sin restricciones, una variable Public es más sencilla y perfectamente
honesta.
¿Qué hace Property Get en VBA?
Property Get es el lado de lectura de una propiedad: se ejecuta cada vez que el
código lee la propiedad, y devuelve el valor (o, para una propiedad de objeto, lo devuelve
con Set). Normalmente va emparejado con un Property Let o Set para la escritura,
envolviendo un campo de respaldo Private —pero un Property Get por sí solo crea una
propiedad de solo lectura o calculada.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 04/08/2026.
Guías relacionadas: VBA Class Module · VBA Type · VBA Dim · VBA Function · VBA ByRef frente a ByVal
