Hoy veremos un sencillo procedimiento para convertir cualquier fórmula (dentro de una rango concreto) en valores...
Lo primero será tener claro qué fórmulas localizadas en qué celdas son las que nos interesa convertir en valores., y para nuestro ejemplo serán las que se encuentran en las celdas C2,D5 y E4:
Con la propiedad .HasFormula detectaremos si nuestras celdas contienen algún tipo de fórmula...
En un módulo del proyecto de VBA para nuestro Libro de trabajo, dentro del Editor de VB:
Tras ejecutar nuestra macro obtenemos el siguiente resultado...lógicamente sólo se habrá producido el cambio en las celdas indicadas!!
Lo primero será tener claro qué fórmulas localizadas en qué celdas son las que nos interesa convertir en valores., y para nuestro ejemplo serán las que se encuentran en las celdas C2,D5 y E4:
Con la propiedad .HasFormula detectaremos si nuestras celdas contienen algún tipo de fórmula...
En un módulo del proyecto de VBA para nuestro Libro de trabajo, dentro del Editor de VB:
Sub ConvierteFormulaenValor() 'recorremos las celdas de nuestro rango elegido For Each rngcell In Range("C2,D5,E4") 'añadimos el control que detecta si la celda tiene Fórmula If rngcell.HasFormula Then 'cuando la tenga asignamos a la celda el valor que tenga.... rngcell.Value = rngcell.Value End If Next rngcell End Sub
Tras ejecutar nuestra macro obtenemos el siguiente resultado...lógicamente sólo se habrá producido el cambio en las celdas indicadas!!
Es mucho más fácil seleccionar el rango, copiar y pegar los valores...
ResponderEliminarHola, muchas gracias por tu comentario...
EliminarSería cierta tu afirmación en casos simples, pero imagina que no son tres casos si no tres mil, y que entre las celdas a convertir tienes otras que te interesa dejarlas como están, i.e, con fórmulas... es ahí donde este sencillo proceso toma sentido.
Un saludo
Entonces porque en el código propuesto se especifia una a una las celdas que se quieren cambiar?
Eliminar....
For Each rngcell In Range("C2,D5,E4")
...
Como tu has dicho: "Imagina que no son tres casos sino tres mil"
Salu2
Hola de nuevo...
Eliminarveo que eres como Santo Tomás... necesitas ver para creer.
Bastaría realizar algún loop FOR NEXT sobre las 3.000 celdas, con una condición IF..THEN o SELECT CASE para excluir las tres celdas.
Saludos
Anonimo, es para VBA principalmente, en algo simple es mejor lo que dices, pero por ejemplo en un archivo con 100,000 filas y 24 columnas todas calculadas, y que desees cambiar sus formulas a valor, donde solo cambias aquellas que cumple sierta condicion para mantener estatico el valor, imaginate recorrer una a una para buscar y cambiar, mejor con macro pongo el criterio de exclusion y cambio todas en segundos.
ResponderEliminarGracias por la exposición!!
EliminarDe acuerdo a este ejemplo, como se podria modificar para que convierta solo las formulas que tuviesen datos y se mantengan en formulas las que no consignan datos.
ResponderEliminarHola Nilto,
Eliminarencantado de saludarte igualmente.
entiendo que con tener dato te refieres a que sea un resultado diferente de cero... si es así, bastaría con añadir al condicional:
If rngcell.HasFormula and rngcell.valu<>0 Then
Espero te funcione
Un cordial saludo
Gracias Ismael por tu respuesta, A tu condicional lo modifique para que se adapte a mis datos.
ResponderEliminarIf rngcell.HasFormula and rngcell.value >=0 Then 'Tengo valores por ejemplo 1 es varon y 0 es mujer'
Pero despues de convertir las formulas en valores me muestra un error "13", No coinciden los datos, que estoy haciendo mal
Tendría que ver los datos..
Eliminar¿puedes enviarme el fichero a excelforo@gmail.com?
Muchas gracias, estimado.
ResponderEliminarPara muchos parece un código sencillo, pero cuando lo combinamos con otros códigos se vuelve indispensable...
Muchos saludos.
;-)
Eliminarmuchas gracias!
Hola Ismael, quiero aplicar el macro que explicaste pero me da error 438 en tiempo de ejecucion y pinta de amarillo la linea if.., soy novato en esto, te agradeceria si lo miras y me decis que esta mal..
ResponderEliminarSub ConvierteFormulaenValor()
'recorremos las celdas de nuestro rango elegido
For Each rngcell In Range("C3:D300")
'añadimos el control que detecta si la celda tiene Fórmula
If rngcell.HasFormula And rngcell.valu <> 0 Then
'cuando la tenga asignamos a la celda el valor que tenga....
rngcell.Value = rngcell.Value
End If
Next rngcell
End Sub
Gracias..
Hola Camilo,
Eliminarsi lo has copiado tal cual, mira la línea:
If rngcell.HasFormula And rngcell.valu <> 0 Then
deberia ser:
If rngcell.HasFormula And rngcell.value <> 0 Then
Saludos
Ismael buena tarde, admiro el trabajo y lo bueno que sos para esto de las macros, yo soy hasta ahora un aficionado con ganas de llegar a tener si quiera la mitad de tu basta experiencia en este tema, quería preguntarte como sería el código en caso tal si solo quiero remplazar las celdas que contengan la función "buscarv" dentro de una hoja específica. Muchas gracias!!!
ResponderEliminarHola Jorge,
Eliminartendrías que emplear la propiedad .Formula o .Formulalocal para recuperar la fórmula de la celda, obtendrías algo así, como string:
=BUSCARV(C6;A6:B9;2;0)
y con algún tratamiento tendrás que condicionar que si los primeros caracteres por la izquierda coinciden con =BUSCARV entonces reemplazar por lo que quieras, su valor u otra cosaa.
Un saludo
Mil Gracias, justo esto era lo que andaba buscando para terminar mi graficadora de funciones (Un proyecto de la Universidad).
ResponderEliminarNunca he programado en VBA de Excel, pero si en otros lenguajes y con lo bien explicado que está tu código he entendido a la primera, aunque lo hayas escrito hace 3 años aún funciona en Office 2016.
Enserio muchas gracias me has salvado el pellejo.
;-)
Eliminarmuchas gracias a tí... me alegro te hay servido
Saludos
Hola, como puedo pasar esta formula de excel a Visual Basic?
ResponderEliminarEl resultado tiene que estar en la celda B16. Esta es la formula:
=SI(D4="chs",BUSCARV(B11,BASE1!C2:I153,3), SI(D4="chr",BUSCARV(B11,BASE1!C2:I153,4)))
Hola Diana
Eliminaren tu macro:
Range("B16").formulalocal="=SI(D4=""chs"",BUSCARV(B11,BASE1!C2:I153,3), SI(D4=""chr"",BUSCARV(B11,BASE1!C2:I153,4)))"
Saludos
Este comentario ha sido eliminado por el autor.
ResponderEliminarEste comentario ha sido eliminado por el autor.
EliminarHola
ResponderEliminarNecesito hacer una macro donde la columna R tiene montos (formulas) y algunos están en cero. En la columna S y T hay montos (formulas) que necesito se transformen en valores, copiando y pegando solos los que contengan en su columna R montos (no considerar los valores en cero) al momento de guardar el archivo. El archivo contiene varias hojas. Solo necesito que la Macro actué en una solo de ellas.
Favor si me puedes ayudar.
Saludos
Hola Tamara,
Eliminarpodrías recorrer el rango de la columna R aplicando una condición para saber si hay o no valor en cada celda.. en caso afirmativo convertir el valor de esa fila para las columnas S y T.
Algo así:
for each celda in range(R1:R100)
if celda.value<>0 then
cells(celda.ror,"S").value=cells(celda.ror,"S").value
cells(celda.ror,"T").value=cells(celda.ror,"T").value
end if
next celda
podrías asociarlo al evento del Workbook beforeClose
Saludos
hola yo deseo quitar formulas de sumar.si de una hoja excel pero contiene otras formulas de suma normal que necesito se queden como puedo hacer la condicionante
ResponderEliminarHola
Eliminartendrías que hacer un reemplazamiento parcial del contenido de la celda, quitando la parte de SUMAR.SI(...)
quizá eliminando hasta le primer '+' o similar, depende de cómo esté introducida la fórmula
Saludos
Buen dia mi problema es el siguiente. Tengo un archivo en Excel con muchas formulas y varias hojas y estan bloqueadas para evitar ser borradas pero quiero que después de 30 dias de uso las formulas queden como valores
ResponderEliminarHola,
Eliminarcon una macro tendrás que controlar el día en que deseas realizar la conversión, para que cuando se abra el fichero verifique ese día y realice le proceso de desbloquear las hojas y recorrer las celdas pasando a valor tus fórmulas...
Hay en el blog algunos ejemplos con las partes que te pueden servir.
Saludos
Buenos días Ismael.
ResponderEliminarAnte todo, muchas gracias por tu extraordinario trabajo. Es de una grandísima utilidad para quienes, como yo, no tienen ni idea de programar y tratan de adentrarse en el mundo de las macros de Excel a base de prueba y error.
Estoy usando la macro que has propuesto y explicado en su versión de búsqueda de todas las celdas con datos en un determinado rango:
Sub Macro1()
For Each rngcell In Range("DATOS2!A2:Q3000")
If rngcell.HasFormula And rngcell.Value <> "" Then
rngcell.Value = rngcell.Value
End If
Next rngcell
End Sub
El problema reside en que la columna A corresponde con datos de fechas, generalmente días laborables pero no siempre es así. Si el ultimo dato de esta columna coincide con el de la celda de otra página (que se importa automáticamente de internet), la macro no se ejecuta y si no coincide se ejecuta siempre. De esta peculiaridad nace la necesidad de borrar las fórmulas de las celdas porque si no las borras al día siguiente los datos se reescriben en la misma celda.
Todo va bien mientras no estés en los primeros 12 días del mes.
Hasta el día 12 el funcionamiento es curioso. Hace bien la primera conversión pero inmediatamente después cambia el mes por el día, usando notación americana en lugar de notación española.
El 05/09/2018 lo convierte en 09/05/2018 y al no coincidir la fecha con la celda de referencia vuelve a ejecutar la macro y así hasta el infinito (bueno, hasta el infinito no, solo hasta que rellena el rango).
He leído por internet que se debe a una asociación erronea del formato de fechas del Excel o de mi ordenador, pero he comproabdo que ambos tienen la misma notación para las fechas y que la selección del formato de celdas es correcta, incluso he quitado el formato automático de fechas y lo he dejado como dd/mm/aaaa.
Pero sigue sin funcionar correctamente. Solo va bien a partir del día 13 y estoy desesperado porque no encuentro la solución. Se me ocurre preguntar si podría intentar comparar la celda de referencia con la fecha del ordenador a través de la funcion Now y escribirla en esa celda en lugar de intentar llegar a ella a través de una simple fórmula que luego hay que eliminar para que no se sobreescriba al día siguiente.
Muchas gracias por tu ayuda por anticipado.
Miguel
Hola,
Eliminarno termino de entender la cuestión... pero parece relacionada con el 'problema' de fechas.
Lo habitual es aplicarle Clng(celda) a las fechas sobre las que trabajar, así la comparativa se realiza sobre el número que representa y suele ser suficiente para salvar el problema...
Espero te oriente
Saludos
Hola tengo una macro que me debe mandar una alarma cuando el stock de un articulo este en 0, funciona bien cuando la celda del stock esta con valor numerico, es decir si lo escribo el cero (0).Ahora el que tengo problema es que la columna del stock esta con formula (=F2-G2) ya que el valor de la columna F le resto el valor de la columna G para que me de el stock. la pregunta es como puedo obtener el valor de esa celda sin perder la formula. anexo macro .
ResponderEliminarPrivate Sub UserForm_Initialize()
Dim i As Long, fila As Long, filan As Long
LBLusuario.Caption = Alerta
Set Busca = Hoja8.Range("I:I").Find(0, , , xlWhole)
i = 0
If Not Busca Is Nothing Then
fila = Busca.Row
filan = fila
Do
LBprod.AddItem
LBprod.List(i, 0) = Hoja8.Range("B" & fila) 'Articulo
LBprod.List(i, 1) = Hoja8.Range("I" & fila) 'Stock
i = i + 1
Set Busca = Hoja8.Range("I:I").FindNext(Busca)
fila = Busca.Row
Loop While fila <> filan
End If
End Sub
Gracias por tu atencion
Hola José
Eliminardisculpa, pero no veo por qué motivo desaparece tu fórmula (F2-G2)...
en tu código solo veo se rellena un listbox (LBProd) en función a los ceros encontrados en la columna I:I de la hoja 8
¿se me escapa algo?
Saludos
hola Ismael! Buenos días disculpa yo realizar una macros para copia algunas columnas de un archivo a otro pero cuando copio me muestra este error #¿NOMBRE? quisiera que al copiar los datos me quite la formula y me deje el valor solamente.
ResponderEliminarmira este es mi macro:
Sub CopiarCeldas()
'Definir objetos a utilizar
Dim wsReport As Excel.Worksheet
Dim rngReport As Excel.Range
Dim matrizMobile_Inventory As Variant
Dim i, j, k As Integer, iCount As Integer
' Se Asigna el rango a la matriz directamente,
' es una matriz con una sola columna
matrizMobile_Inventory = Range("H7:H461")
Set wsReport = Worksheets("REPORT")
' Se Obtiene el tamaño del rango
iCount = Tamanio(Range("H7:H461"))
' se Inicializa el contador para guardar los datos
j = 2
' se escriben los datos validando los campos vacios
For i = 1 To iCount - 1
If Not (IsEmpty(matrizMobile_Inventory(i, 1))) Then
wsReport.Range("C" & j) = matrizMobile_Inventory(i, 1)
j = j + 1
End If
Next i
End Sub
Hola Aleiram
Eliminar¿has pensado en hacer un sencillo
Range(...).Copy
Sheets(...).range(..).pastespecial Paste:=xlPasteValues
teniendo en cuenta el libro destino (o la hoja destino dentro de tu libro)
Saludos
Hola Ismael, mi nombre es Esteban, vi este comentario y necesito hacerte una consulta, necesito copiar el resultado de una formula en otra hoja, es algo asi, =+si(P4<>p5;h4+h5+h6;h5+h6) el resultado seria ej para verdadero 100 y para falso 20, pero cuando ejecuto la macro me pone siempre 20, no se que puedo estar haciendo mal, estoy usando el código
EliminarSheets("Hoja2").Select
Range("I3").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Hoja4").Select
Range("P17").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Hoja2").Select
Application.CutCopyMode = False
desde ya muchas gracias y perdon si me extendí
Hola,
Eliminarsupongo que en la celda P17 tienes esa fórmula que comentas:
=+si(P4<>p5;h4+h5+h6;h5+h6)
y en tu macro copias el resultado que hubiera en ese momento y lo pegas como valores... asi que devolverá siempre el mismo valor mientras las condiciones de la prueba lógica (P4<>P5) no cambien...
Slds
intente ingresar el codigo asi pero me genera error
ResponderEliminarPrivate Sub GeneraReporte(sRuta As String, sRango_Ini As String, sRango_Fin As String)
'se crea variable se hace referencia al libro del cual donde se va hagarrar la informacion
Dim LibroDatos As Workbook
Dim n As Integer
Dim FilePath As String
FilePath = Dir(sRuta)
On Error GoTo 0
If FilePath = "" Then
MsgBox "El archivo " & sRuta & " no existe", vbInformation, "File"
Else
'se abre el archivo donde contiene la informacion
Set LibroDatos = Workbooks.Open(sRuta)
LibroDatos.Sheets(14).Range(sRango_Ini).Copy
n = Application.WorksheetFunction.CountA(LibroDatos.Sheets(14).Range(sRango_Ini))
Application.DisplayAlerts = False
LibroDatos.Close Savechanges:=False
If n <= 0 Then
MsgBox "El archivo: " & sRuta & " no contiene datos"
Else
ActiveSheet.Range(sRango_Fin).PasteSpecial Paste:=xlPasteValues
iLetra = iLetra + 2 ' se debe de incrementar iLetra para obtener la letra que corresponda
End If
End If
End Sub
si le quito esta parte de codigo y gala los datos normal.
Hola
Eliminarenvíame si quieres el fichero a
excelforo@gmail.com
Slds
Hola Ismael!, primero que nada muchas gracias por el tutorial, tengo una duda sobre el rango de la macro cuando uno tiene varias hojas y requiere que en una en especifico no se muestre la formula, me arroja el error 104 ( anterior a esto tengo otra macro que hace los cálculos):
ResponderEliminarSub ConvierteFormulaenValor()
For Each rngcell In Hoja9.Range("G2:G")
If rngcell.HasFormula Then
rngcell.Value = rngcell.Value
End If
Next rngcell
End Sub
Hola Paula,
Eliminartendrías que condicionar el nombre de la hoja
Sub ConvierteFormulaenValor()
for each sh in worksheets
if sh.name<>"Hoja a excluir" then
For Each rngcell In Hoja9.Range("G2:G")
If rngcell.HasFormula Then
rngcell.Value = rngcell.Value
End If
Next rngcell
end if
next sh
End Sub
Saludos
Hola Ismael, aun me arroja el error 104 por la siguiente linea : For Each rngcell In Hoja9.Range("G2:G") .
ResponderEliminarSaludos
faltaría indicar el rango correcto
EliminarHoja9.Range("G2:G100")
G2:G no es un rango válido
;-)
Buen día.
ResponderEliminarTengo el siguiente problema: al momento de ejecutar la macro, debe buscarme el valor en la columna A que coincida con la celda h4 de la primera hoja ("h1"), sin embargo no lo hace porque la columna A no tiene valores como tal, sino la fórmula =Fila() para que me devuelva el valor de la fila. Como puedo hacer que la búsqueda del valor de celda H4 en la columna A sea exitosa?
Sub Reemplazar()
Set h1 = Sheets("reporte")
Set h2 = Sheets("database")
cf = MsgBox("Desea reemplazar el registro?", vbInformation + vbYesNo, "AVISO")
If cf = vbYes Then
If h1.[H4] = "" Then
MsgBox "Colocar número de FOLIO"
Exit Sub
End If
Set r = h2.Columns("A") 'Aquí tengo el problema
Set b = r.Find(h1.Range("H4"), LookAt:=xlWhole, SearchFormat:=False)
If Not b Is Nothing Then
h2.Cells(b.Row, "AA") = h1.[b52]
MsgBox "Se ha reemplazado con éxito", vbInformation
Else
MsgBox "El código no existe", vbInformation
Exit Sub
End If
Limpiar
End If
End Sub
Hola William
Eliminarprueba cambiando
Set r = h2.Columns("A") 'Aquí tengo el problema
por
Set r = h2.Columns(1) 'Aquí tengo el problema
o por
Set r = h2.Columns("A:A") 'Aquí tengo el problema
Saludos
Que tal Ismael.
EliminarPude probar lo que me recomiendas, sin embargo el código sigue sin poder encontrar el valor buscado en la columna A. Mi suposición es que no puede comparar el valor debido a que la columna A está armada con la formula =Fila() para asignarle un valor.
Hola....
Eliminarraro ?
añade a tu búsqueda las opción de buscar como valores:
LookIn:=xlValues,
así:
Set b = r.Find(h1.Range("H4"), LookIn:=xlValues, LookAt:=xlWhole)
asegúrate de qué estas buscando en H4
Slds
Ya quedó, Muchas gracias.
ResponderEliminarBuenas tardes!! Qué tal... Tengo una duda:
ResponderEliminarSi deseo que solamente las formulas contenidas en las celdas de un cierto rango en específico (aquellas celdas en las que la fórmula ya arrojó un valor) se conviertan en valores fijos automáticamente al momento de GUARDAR el Libro, qué MACRO podría usar?...
Me interesa que el usuario no tenga que preocuparse de convertir fórmulas a valores cada vez que utilice el Libro, y que los valores calculados por la fórmulas no se vean afectados retroactivamente cuando la base de datos se modifique.
Tengo mucho tiempo intentado lograrlo!
Gracias de antemano...
Hola DanielG,
Eliminaremplea el evento de libro _BeforeSave y aplica la macro del ejemplo del post para convertir el rango deseado a valores...
Saludos
Hola Ismael!, tengo una duda para implementar una macro, debo de copiar un rango de filas de un libro e insertarlas en un libro nuevo. El inconveniente radica en que los datos contenidos en las filas del libro de origen contienen fórmulas y solo debo de llevar al nuevo libro valores y formatos.
ResponderEliminarLas filas las estoy insertando con el comando: Selection.Insert Shift:=x1Down y posteriormente hacía un Selection Copy sobre las filas insertadas en el nuevo libro y finalmente un PasteSpecial xlPasteValues sobre las filas pero no me estaría funcionando. Gracias!
Hola,
Eliminarecha un vistazo a estas formas de copiar/pegar datos con macros
https://excelforo.blogspot.com/2011/02/vba-formas-de-copiar-rangos-o-celdas.html
En tu caso igual te resulta más cómodo usar.
yyyy.value = xxxx.value
Un saludo
Este comentario ha sido eliminado por el autor.
ResponderEliminarQue tal Ismael?, mi nombre es Claudia y quisiera consultarte acerca de un código en VBA. Tengo que hacer un código y donde necesito leer una celda de mi excel, la cual corresponde a una formula y resulta que VBA no la esta leyendo, he probado de todo, no tengo mal anotada la forma porque cuando escribo algo o coloco un numero en la celda, VBA lo lee bien, pero cuando coloco la formula no pasa nada, no se si explico bien mi problema.
ResponderEliminarte agradecería información o/y orientación al respecto.
Gracias!!
Hola Claudia,
Eliminar¿podrías indicar tu código y qué hay escrito (la fórmula) en esa celda?
Entiendo quieres que la macro te devuelva la fórmula y no el valor resultado??
Slds
Hola, necesito que la macro lea el valor de la celda no la formula. Mira mi código lo tengo escrito así
EliminarFor k = 1 To 1000
Select Case pointer
Case 1: a = Worksheets("Hoja1").Range("$AB$7").Value
x(2) = x(1) + step
b = Worksheets("Hoja1").Range("AB7").Value
If b < a Then
j = 2
pointer = 2
Para ir variando y probar que tengo mal puso el signo "$" pero tampoco me resulto. Como dato tengo declarada las variables como "string" "variant" o "double" y con ninguno me leyó el valor de la celda.
La celda en cuestión corresponde a la suma de otras celdas.
Celda AB7 =G7+L7+Q7+V7+AA7
Y cada una de las otras celdas corresponde a la suma de datos de su respectiva columna.
El asunto es que cuando corro la depuración "a" y "b" quedan como valores vacios (y cuando la declaro como variant salen ""). Pero cuando coloco el valor como numero si lo lee o incluso lee el texto. Para mi codigo en general yo necesito que excel lea el valor porque va ir variando, ese es la gracia.
En fin, no se si haya otra forma de leer el valor de la celda. Sino tendré que ver otra forma de escribir mi codigo desde 0.
Gracias por tu tiempo!!!!
Hola Claudia,
Eliminar¿ese es todo tu código?... veo muchos sin sentido
un bucle FOR si NEXT
un SELECT CASE sin END SELECT
una matriz x sin definir
un 'pointer' no asociado a k
un IF sin END IF
etc
???
Para recuperar el valor de la celda es suficiente como lo has hecho
b = Worksheets("Hoja1").Range("AB7").Value
así cargas a la variable b el valor de AB7
Si no ves lo que esperas es por el resto de la programación extraña...
Un saludo
No es todo el código, solo te copie lo de interés, no me sirve anotarlo de la forma que me dices, el valor de la celda AB7 no se esta cargando a ninguna variable. No importa, gracias por tu tiempo, veré otra forma de hacerlo. Saludos
EliminarEn el detalle reside la diferencia...
EliminarEntre las líneas que indicaste tenías
b = Worksheets("Hoja1").Range("AB7").Value
donde cargas en la variable b el valor de AB7
si no está cargándolo es por que el resto del código está evitando que lea esa línea...
slds
Este comentario ha sido eliminado por el autor.
ResponderEliminar