TL;DR —
Columns("C").Insertno hace aparecer una columna en blanco de la nada. Empuja la columna C y todo lo que hay a su derecha una columna más a la derecha, y Excel reescribe cada fórmula que apuntaba a esa región para que siga cayendo sobre los mismos datos. Insert es un desplazamiento. Dos reglas lo mantienen seguro: opera sobre la columna entera (Columns(...)o.EntireColumn, nunca un rango parcial), e inserta varias columnas en una sola llamada en lugar de una a una en un bucle hacia delante.
Sub InsertMarginColumn()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Report")
ws.Columns("D").Insert CopyOrigin:=xlFormatFromRightOrBelow
ws.Columns("D").ClearFormats ' empieza limpia la columna nueva, no con el estilo de la vecina izquierda
End Sub
Insertar una columna, eliminar una columna e insertar o eliminar un rango parcial son la misma idea con
tres disfraces: todas desplazan físicamente la cuadrícula, y todo se desplaza con ellas —incluidas las
referencias de las fórmulas, que o bien siguen a los datos o bien estallan en #REF!—. Las operaciones
sobre la columna entera se desplazan en una única dirección sin ambigüedad, así que son el caso seguro.
Domina esta y las otras dos son casi el mismo mecanismo apuntado a algo más estrecho.
Lo que aprenderás
- El modelo mental — Insert hace sitio empujando, no vaciando
- La única regla que evita los diseños rasgados — inserta la
EntireColumn, nunca un rango parcial - Por qué tus fórmulas sobreviven a una inserción pero las direcciones fijas de tu VBA no
- Cómo insertar varias columnas de una vez, y por qué un bucle hacia delante las dispersa
- La regla de
CopyOrigindetrás de «¿por qué mi columna nueva ya tiene formato?»
El modelo mental: Insert empuja, no vacía
Columns("C").Insert no es «pon una columna en blanco en C». Es «haz sitio en C empujando a todos hacia
la derecha». La columna C pasa a ser la D, la D pasa a ser la E, y así hasta el borde de la hoja. Los
datos de la vieja columna C no han desaparecido: se han movido. Una columna en blanco es sencillamente el
hueco vacío que queda en el punto de inserción.
Esto importa porque un desplazamiento tiene consecuencias que un vaciado no tendría. Cuando los datos
se mueven, Excel mueve las referencias con ellos: una fórmula que está tres hojas más allá y decía
=SUM(C2:C100) pasa a decir =SUM(D2:D100) en el instante en que insertas antes de C, porque Excel la
mantiene apuntando a los mismos números. Eso es la funcionalidad. La trampa, más abajo, es que tu código
VBA no recibe el mismo trato.
La regla que más importa: inserta la EntireColumn
Toda inserción fiable opera sobre una columna entera:
ws.Columns("C").Insert ' una columna completa antes de C
ws.Range("C:C").EntireColumn.Insert ' identico, escrito por extenso
La forma número uno de rasgar un diseño es insertar en su lugar un rango parcial:
ws.Range("C1:C10").Insert Shift:=xlShiftToRight ' desplaza solo 10 celdas a la derecha
Eso empuja diez celdas hacia la derecha mientras el resto de la columna C se queda quieto —un escalón
dentado clavado en mitad de la cuadrícula, con las filas de la 11 en adelante ya desalineadas respecto a
las filas 1–10—. Se ejecuta sin error y parece correcto hasta que alguien baja con el scroll. La regla es
sencilla: para insertar una columna, nombra una columna —Columns(...) o .EntireColumn—. Las
inserciones de rango parcial son una herramienta de verdad, pero son otro trabajo (que se cubre en
VBA Insert Cells), y recurrir a una cuando querías «una columna» es el fallo.
Las referencias siguen a los datos, pero tu código no
Esta es la asimetría que sorprende a la gente. Inserta una columna antes de C y:
- Las fórmulas de la hoja se ajustan.
=D5*E5,=VLOOKUP(A2, C:F, 2, 0), el rango de origen de un gráfico —Excel las reescribe todas para que sigan apuntando a los mismos datos—. No tienes que tocarlas. - Las direcciones fijas en tu VBA no se ajustan. Si tu macro ejecuta más tarde
ws.Range("D5").Value = 100, ese literal"D5"sigue significando la celda de la columna D, fila 5 —pero tras la inserción esa es una celda distinta de la que tenías en mente—. La cadena de texto no sabe que ha aparecido una columna a su izquierda.
Así que el peligro no es la inserción en sí, sino el código escrito antes de la inserción que da por hecho el diseño viejo. Dos defensas, por orden de preferencia:
' 1. Captura lo que te importa como objeto ANTES de insertar - el objeto sigue el movimiento
Dim total As Range
Set total = ws.Range("D5")
ws.Columns("C").Insert
total.Value = 100 ' sigue siendo la celda correcta; el objeto siguio al desplazamiento
' 2. O localiza las columnas por el nombre del encabezado DESPUES de insertar, nunca por una letra fija
Dim col As Long
col = ws.Rows(1).Find("Amount", LookAt:=xlWhole).Column
El criterio: trata cualquier dirección de celda literal como caduca en el momento en que insertas o
eliminas cerca de ella. Guarda las referencias como objetos Range, o búscalas por un encabezado que
puedas localizar por su nombre.
Inserta varias columnas en una sola llamada
Para insertar tres columnas, inserta un rango de tres columnas:
ws.Columns("C:E").Insert ' aparecen tres columnas antes de C, en un solo desplazamiento
No insertes una columna tres veces en un bucle hacia delante:
Dim i As Long
For i = 1 To 3
ws.Columns("C").Insert ' MAL - cada insercion empuja a la siguiente
Next i
Cada Insert renumera todo lo que hay a su derecha, así que la «C» de la segunda iteración no está donde
crees. Acabas con columnas dispersas por la hoja en vez de un bloque limpio. Es la misma trampa de
renumeración que hace que eliminar en un bucle hacia delante se salte columnas —la imagen especular, que
se cubre en VBA Delete Column—. Inserta el bloque en una sola instrucción
o, si las posiciones se calculan y hay que iterar, trabaja de derecha a izquierda para que las
inserciones tempranas nunca muevan los objetivos posteriores.
CopyOrigin: por qué la columna nueva llega ya con formato
Una columna recién insertada no está de verdad en blanco: por defecto hereda el formato de la columna
que tiene a su izquierda (CopyOrigin:=xlFormatFromLeftOrAbove, el valor por defecto). Si la vecina de
la izquierda es un total en negrita o una banda sombreada, tu «nueva» columna «vacía» aparece en negrita o
sombreada. Esta es la respuesta a «¿por qué mi columna insertada ya tiene estilo?».
ws.Columns("D").Insert CopyOrigin:=xlFormatFromRightOrBelow ' hereda de la vecina DERECHA en su lugar
' - o - toma el valor por defecto y luego borralo:
ws.Columns("D").Insert
ws.Columns("D").ClearFormats
Elige a conciencia. Heredar de la izquierda es lo correcto cuando estás extendiendo un bloque con formato; borrar el formato es lo correcto cuando quieres una columna genuinamente nueva. Lo que hay que evitar es dejarlo en el valor por defecto y llevarte una sorpresa.
Cómo te ayuda ExcelMaster
Insertar una columna parece una sola línea y esconde tres decisiones —insertar la columna entera (no un rango parcial), mantener válidas tus referencias posteriores a lo largo del desplazamiento y controlar de qué vecina hereda el formato la columna nueva—, y equivocarse en cualquiera de ellas falla en silencio: un diseño rasgado, una macro que ahora escribe en la celda equivocada o una columna en negrita colada de rondón.
ExcelMaster te deja decir lo
que quieres —«inserta una columna de margen después de Amount, sin formato, y mantén intacta la fórmula de
totales»— y escribe el EntireColumn.Insert, localiza la columna por su encabezado en vez de por una letra
fija, ajusta CopyOrigin (o borra el formato) para que encaje, e inserta un bloque de varias columnas en
una sola llamada cuando pides varias. Tú conservas el libro y el código.
Preguntas frecuentes
¿Cómo inserto una columna en VBA?
Usa Columns("C").Insert para insertar una columna completa antes de la columna C. Todo lo que va de C
hacia la derecha se desplaza una columna a la derecha, y las fórmulas de la hoja que referenciaban esas
celdas se ajustan automáticamente. Prefiere la forma cualificada
ThisWorkbook.Worksheets("Report").Columns("C").Insert para que no dependa de cuál sea la hoja activa en
ese momento.
¿Cómo inserto varias columnas a la vez?
Inserta un rango de varias columnas: Columns("C:E").Insert inserta tres columnas antes de C en un solo
desplazamiento. No repitas Columns("C").Insert tres veces en un bucle —cada inserción renumera las
columnas que tiene detrás, así que las repeticiones caen en los sitios equivocados—. Una sola llamada, un
bloque limpio.
¿Por qué mi columna insertada ya tiene formato?
Porque Insert copia por defecto el formato de la columna que tiene a su izquierda
(CopyOrigin:=xlFormatFromLeftOrAbove). Pasa CopyOrigin:=xlFormatFromRightOrBelow para heredar de la
derecha en su lugar, o llama a .ClearFormats sobre la columna nueva después para dejarla genuinamente en
blanco.
¿Se rompen mis fórmulas al insertar una columna?
Las fórmulas de la hoja no se rompen: Excel reescribe sus referencias para que sigan a los datos a lo largo
del desplazamiento. Lo que no se actualiza es una dirección fija en tu VBA, como Range("D5"): ese
literal sigue apuntando a la columna D, que ahora es una celda distinta. Captura las celdas como objetos
Range antes de insertar, o localízalas después por el nombre del encabezado.
¿Cómo inserto una columna antes de un encabezado concreto en vez de una letra fija?
Localiza el encabezado y luego inserta sobre su EntireColumn:
Rows(1).Find("Amount", LookAt:=xlWhole).EntireColumn.Insert. Esto sobrevive a los cambios de diseño,
porque localiza la columna por lo que es y no por dónde está situada ahora mismo.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 15/09/2026.
Guías relacionadas: VBA Delete Column · VBA Insert Cells · VBA Insert Rows · VBA Hide Columns · VBA Column Width
