Seleccionar filas de un formulario en access y las añada a una hoja excel

Necesito una macro o código VBA que me seleccione algunas celdas de un subformulario en modo hoja de datos y añada los valores de esas celdas a una hoja excel preexistente, por ejemplo a las celdas A1 y A2 de una hoja denominada "Hoja1"

Se trata del subformulario "DatosTandas Subformulario" del formulario "Tandas" de la base de datos que incluyo aquí: http://www.filebig.net/files/ZgdTj66587

Se trataría de seleccionar aquellas filas que cumplan una determinada condición, como que el valor del campo "ValorCalculado" sea mayor que 5, pero que sólo exporte los campos "Codigo" y "ValorCalculado" de cada fila.

1 respuesta

Respuesta
1

Aquí tienes una forma de hacerlo: http://www.filebig.net/files/dNvgeGhKUt 

Está basada en este ejemplo de Neckkito: http://neckkito.xyz/nck/index.php?option=com_content&view=article&id=177:exportar-a-hoja-existente-en-excel&catid=18:codigo 

He supuesto que quieres exportar los datos del subformulario que se correspondan al registro del formulario principal que tienes en pantalla al pulsar el botón (que es donde está programado el código). Si no fuera así, y quieres exportar todos los que cumplan la condición de que el ValorCalculado sea mayor que 5 (yo he puesto mayor o igual en el código), simplemente elimina de la SQL el "... AND IdTanda= & Me.IdTanda

Fantástico!. Sólo una cosa, en la línea:

miSQL = "SELECT Codigo, ([Valor1]+[Valor2])/2 As ValorCalculado FROM DatosTandas WHERE (([Valor1]+[Valor2])/2)>=5 AND IdTanda=" & Me.IdTanda

Se vuelve a calcular el ValorCalculado como el promedio. ¿no puede tomarse directamente el valor del campo calculado? Lo digo porque en la base que estoy programando el ValorCalculado tiene un sistema de cálculo mucho más complejo que un promedio, y no puedo meterlo en una línea como esa.

El "problema" está en que en la Bd que subiste, el cálculo lo haces en el propio formulario, pero no se guarda en ninguna tabla, ni lo haces en una consulta que uses como origen del formulario, y por tanto, necesitas calcularlo en la sql para que puedas hacer el traspaso de los datos que te interesa.

En cualquier caso, por muy complejo que sea el cálculo, no veo problema a que lo metas en la sql. Y es más, si se te complica, puedes crear una función pública en VBA y usarla en la sql. Por ejemplo, en tu ejemplo:

Public Function elCalculo ( unValor as Double, otroValor as Double) as Double

elCalculo =  (unValor + otroValor)/2

End Function 

Y la sql quedaría :

miSQL = "SELECT Codigo, elCalculo([Valor1],[Valor2]) As ValorCalculado FROM DatosTandas WHERE elCalculo([Valor1],[Valor2])>=5 AND IdTanda=" & Me.IdTanda

Ok, te adjunto esta base de datos con el formulario real con el que estoy trabajando.

http://www.filebig.net/files/vL4DArWbHs 

En este formulario en modo hoja de datos consignamos varios datos, y el último campo de cada registro es un campo calculado con el resultado final. Para hallar ese resultado verás que he tenido que crear por detrás varios campos calculados que hacen diversas operaciones...no sé como trasladar esto a una única función en VBA, es muy complejo para mí. Muchas gracias por tu ayuda.

La fórmula que tienes para calcular el campo "CalcResultado" no es del todo correcta, ya que prácticamente en todos los registros devuelve un error (si la fórmula estuviera bien expresada, no debería dar error, sino algún valor). Como no soy capaz de ver el error, ni sé que tiene que hacer la fórmula, te subo el archivo con dos opciones "aproximadas", teniendo en cuenta que los resultados no son los mismos que tu obtienes: http://www.filebig.net/files/i77ewFy9f4

El formulario Opcion1 se basa en la consulta CAux, que es una consulta sobre la tabla, con los cálculos hechos en la propia consulta, en vez de en el formulario. El problema está en que al dar error CalcResultado, el error se extiende al Resultado final. Si solucionas la fórmula, arreglado.

El Formulario Opción2 se basa en una fórmula directa en el último cuadro de texto Resultado, sobrando todos los cuadros de texto con los cálculos intermedios. La fórmula es muy probable que tenga algún error por los copia-pega, pero te puedes hacer una idea de cómo habría que hacerlo. La clave está en ir declarando variables para los cálculos intermedios, y hacer esos cálculos, y así hasta llegar al cálculo final.

En la función hay un control de errores, porque me saltaba un error de "desbordamiento" (supongo que por alguna división por 0, pero no lo sé seguro), e igual no es la mejor solución, pero...

Muchas gracias!!. No hay problema con la fórmula de calcresultado, de hecho hay un control de errores en el campo Resultado que es el que interesa. Es cierto que en muchos registros da error, pero tiene sentido que así sea, tenemos muy comprobados que los cálculos que proporciona sean correctos. El valor de este campo es empleado luego por el campo resultado, quien toma decisiones en función de si el anterior ha dado error o no. Sí que hay registros con resultado, aquí te muestro algunos.

Veo perfectamente cómo lo has traducido a VBA, genial, ahora me pondré a revisarlo, Muchísimas gracias por tu ayuda!!

Hola, he intentado trasladar todo lo que hemos avanzado a mi base de datos, pero no logro pasar de un error de coincidencia de tipos que aparece al lanzar la exportación a excel a través del ejemplo de Neckkito...no logro aislar el error. Te adjunto la base aquí. Lo hago a través de un botón que he creado "Exportar a Excel" en el formulario Tandas Aerobios 22ºC.

http://www.filebig.net/files/hGnRHpbv78 

Te agradezco enormemente tu ayuda....

Por lo que veo, tienes dos "problemas":

1º/ En el editor de VBA te falta registrar una de estas dos referencias (pero solo uno, porque son incompatibles entre sí):

Microsoft DAO 3.6 Object Library

Microsoft Office 12.0 Access Database Engine Object Library

En esta última igual el número de versión es diferente, según tu versión de Office.

2º/ Si con solo registrar esas librerías no se soluciona el problema, cambia las lineas: Dim rst As Recordset y Dim fld As Field por estas otras: Dim fld As DAO.FieldDim rst As DAO.Recordset . y CA

Yo probé y me funciona.

Solucionado registrando DAO 3.6 y cambiando las líneas indicadas!! Muchas Gracias!!

Vuelvo a recurrir a tí...necesito que antes de pegar los registros en la excel, se borren los datos de la columna A de la hoja 1 de excel. Para ello, he introducido esta línea que te copio en cursiva en el código:

.......

'Abro el Excel seleccionado
miExcel.Workbooks.Open rutaExcel, True, False

'Borramos columna A y guardamos
Range("A:A").Delete
.......

Al ejecutar, la primera vez lo hace bien (borra los datos de la columna A y pega los registros seleccionados), pero si vuelvo a ejecutar el código me dice que no encuentra la hoja excel. Hasta que no salgo de la base de datos no vuelve a funcionar. Muchas gracias,

Como estás programando en Access, tienes que indicar que el borrado lo va a hacer en el excel que has abierto:

miExcel.Range("A:A").Delete

en vez de solo:

Range("A:A").Delete

Perfecto! Me funciona bien con una hoja excel de pruebas, vacía sin datos ni nada más. Pero la hoja real que quiero emplear (D:\Laboratorio\Varios\Comunicaciones incumplimientos MB.xlsx) tiene otros datos, y está conectada a otra base de datos access, de tal modo que al abrirse descarga una serie de datos en su Hoja3, y los combina con los datos que deberían pegarse desde access.....Por lo que sea, esta excel no es capaz de encontrarla, aunque la ponga en la misma ruta que la hoja de pruebas. Me da el error de que no encuentra la hoja excel. No es un error de nombre de la ruta, cualquier excel con cualquier nombre en esa ruta me la encuentra, pero esta excel en concreto, no. ¿Alguna pista, por favor? Te copio mi actual código:

'Neckkito @ http://siliconproject.com.ar/neckkito/
'12/03/14
'Requiere registro de la referencia "Microsoft Excel x.y Object Library"
On Error GoTo sol_err
'Declaramos las variables
Const nombreHoja As String = "Hoja1" 'Aquí indicamos el nombre de la hoja existente en el Excel
Dim miSQL As String
Dim miExcel As excel.Application
Dim rutaExcel As String
Dim i As Long, j As Long
Dim fld As DAO.Field
Dim rst As DAO.Recordset
'Construimos la ruta del Excel
rutaExcel = "D:\Laboratorio\Varios\Comunicaciones incumplimientos MB.xlsx"
'NOTA: si tenemos el Excel en otra ubicación deberíamos cambiar la línea anterior por la de
'la ruta. Por ejemplo:
' rutaExcel = "c:\MisExcel\DatosEnero\nombreExcel.xls"
'----------------------------------------------------------------------------------------------

'Creamos la SQl que nos dará los registros a exportar:
miSQL = "SELECT cod_muestra FROM Dtaerob22C WHERE IdTanda=" & Me.IdTanda
'Creamos el recordset sobre la tabla -o consulta, si fuera el caso-
Set rst = CurrentDb.OpenRecordset(miSQL)
'Si no hay registros en la consulta salimos
If rst.RecordCount = 0 Then
MsgBox "No existen datos para exportar", vbExclamation, "SIN DATOS"
Exit Sub
End If
'Creo el objeto Excel
Set miExcel = CreateObject("Excel.Application")
'Lo hago no visible

miExcel.Visible = False
'Abro el Excel seleccionado
miExcel.Workbooks.Open rutaExcel, True, False
'Borramos columna A y guardamos
miExcel.Range("a4:a100").Delete
'Sitúo el cursor en el reloj de arena porque el proceso puede ser largo
DoCmd.Hourglass True
'Borramos columna A y guardamos
miExcel.Range("a:a").Delete
'Inicializamos i y j
i = 4
j = 0
'Nos movemos al primer registro
rst.MoveFirst
'Iniciamos el proceso
Do Until rst.EOF
'Recorremos los campos de la tabla o consulta
For Each fld In rst.Fields
miExcel.Worksheets(nombreHoja).Range("A1").Offset(i, j).Value = rst.Fields(fld.Name).Value
'Aumentamos una columna
j = j + 1
Next fld
'Aumentamos una fila
i = i + 1
'Reinicializamos j
j = 0
'Nos movemos al siguiente registro
rst.MoveNext
Loop
'Volvemos a situar el puntero en su posición normal
DoCmd.Hourglass False
'Lanzamos un mensaje de confirmación
MsgBox "Exportación realizada correctamente", vbInformation, "CORRECTO"
'Guardamos el Excel y lo cerramos
miExcel.ActiveWorkbook.Save
Salida:
miExcel.Workbooks.Close
miExcel.Application.Quit
Set miExcel = Nothing
Exit Sub
sol_err:
'Volvemos a situar el puntero en su posición normal
DoCmd.Hourglass False
'Gestionamos los errores error que pudieran producirse
Select Case Err.Number
Case 9 'No existe la hoja
MsgBox "La hoja donde se quieren exportar los datos no" _
& " existe en el Excel", vbCritical, "ERROR"
Case 1004 'No existe el Excel
MsgBox "El Excel donde quiere exportar los datos no existe", _
vbCritical, "ERROR"
Case Else
MsgBox "Se ha producido el error " & Err.Number & " - " & Err.Description, _
vbCritical, "ERROR"
End Select
Resume Salida
End Sub

Ni idea de qué pista darte, porque pueden ser mil cosas...

Haz una cosa: comenta (o elimina) la lineal del principio que dice "On Error GoTo sol_err", ejecuta el nombre y mira a ver en qué lineal te da el error, su número y su descripción (y dímelos, claro...)

Y cuando pongas código, usa la opción de "insertar código fuente", porque hace que sea mucho más fácil de leer

Error 1004

Error en el método delete de la clase range

Se me abre el depurador y me señala esta línea:

miExcel.Range("a4:a100").Delete

Quiero borrar las celdas A4 a A100 antes de pegar los nuevos registros.

OK, lo he intentado manualmente, y el problema es que la hoja excel está protegida...por eso da el error. Imagino que tendré que desproteger ese rango específico antes de copiar los datos.

¡Muchas gracias, otra vez!

Y el comando para vaciar las celdas es erase, no delete. Parece ser que delete elimina las celdas ¿correcto?

Efectivamente, si la hoja (o el rango) están protegidos, no puedes manipular los valores de esas celdas protegidaspor código, igual que tampoco puedes hacerlo directamente en la hoja.

Ok, pero sólo son algunas celdas las que están protegidas. Precisamente las celdas donde quiero pegar los registros están desprotegidas, y sin embargo, me dice que están en una hoja protegida. En la hoja directamente sí que puedo hacerlo. Voy a ver cómo desproteger la hoja por código, y que después de pegar los registros la vuelva a proteger. ¡Gracias!

Pues ahí poco te puedo ayudar, mi fuerte es el código VBA de Access no el VBA de Excel..., pero supongo que buscando un poco por google, encontrarás los códigos necesarios. Solo recuerda lo que te decía antes, tienes que indicar primero que el código tiene que trabajar en el excel abierto (con miExcel. Xxxxx)

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas