Saltar al contenido

RECORDSET


Recommended Posts

Buenos compañer@s, a ver si me podéis ayudar con esta macro. En esencia se conecta al AS400 de mi empresa (previa vista generada) y me trae datos a través de una consulta SQL. La macro funciona bien y no tengo problemas. El tema es que no sé trabajar recorriendo el  RECORDSET y me toca ingeniármelas con un bucle Do Loop para que me vaya generando los datos que quiero. Os detallo la macro y las celdas donde me trae los datos. Lo que me gustaría es poder establecer el rango("C5:C18") de alguna forma en el RECORDSET para que lo hiciese de golpe y no recorriendo celda a celda. Asimismo, si por ejemplo, quisiese ampliar el rango de la matriz de datos y meter, por ejemplo, en D3 el mes 11, en D4 el mes 12, que me trajese los datos.

Muchas gracias

imagen.png.862e9b48a63faa8dc696fbc7e2ab43dd.png

 

Option Explicit
Option Base 1

Public Sub VENTAS_SECCION_MES()

Dim sql As String, SheetName As String
Dim AÑO, CENTRO, SECCION, MES As String

Sheets("Ventas").Select
Range("C5").Select

Do Until ActiveCell.Offset(0, -1) = ""

AÑO = Range("C2").Value
CENTRO = Range("A3").Value
MES = Range("C3").Value
SECCION = ActiveCell.Offset(0, -2).Value

Application.Cursor = xlWait
Dim wb As Workbook, ws As Worksheet

'Venta de un año, un mes, una tienda y una sección
sql = _
"SELECT SUM(TOT_VENTAS) AS TOTAL_VENTAS " & _
  "FROM PRESUPUESTO_VENTAS " & _
 "WHERE ANYO = " & AÑO & " AND COD_CC = " & CENTRO & " AND SECCION= " & SECCION & " AND MES= " & MES & " "

SheetName = "Ventas"

Set wb = ActiveWorkbook

Set ws = wb.ActiveSheet
ws.Name = SheetName


' Poner los datos particulares de la conexión

Dim Con As New ADODB.Connection
Con.Open "provider=IBMDA400;data source=172.16.1.1;Default Collection=-------;USER ID=-----;PASSWORD=-------;"


DownloadQuery Con, sql, SheetName

ActiveCell.Offset(1, 0).Select

Con.Close

Loop

Set Con = Nothing
Set wb = Nothing
Set ws = Nothing

Application.Cursor = xlDefault

End Sub


Private Sub DownloadQuery(Con As ADODB.Connection, sql As String, SheetName As String)

Dim Cmd As ADODB.Command
Dim Rs As ADODB.Recordset

Set Cmd = New ADODB.Command
Set Cmd.ActiveConnection = Con
Cmd.CommandText = sql

Dim ws As Worksheet, fld As ADODB.Field

Set ws = Worksheets(SheetName)

Set Rs = Cmd.Execute()


' Me trae el dato de la Consulta SQL

ActiveCell.CopyFromRecordset Rs

Set fld = Nothing
Set Rs = Nothing

End Sub

 

imagen.png

Enlace a comentario
Compartir con otras webs

Hola

Es complicado terminar de entenderte sin tener acceso a tu base de datos. Sugiero colocar en una hoja de Excel una copia fiel de una parte de los registros de la tabla "PRESUPUESTO_VENTAS" para poder entender tu bucle y lo de los parámetros usados en la sentencia SQL. No olvidar una mejor y detallada explicación. OJO, repito, parte de los datos de la tabal, tal cual, no de los datos extraídos como has adjuntado.

Enlace a comentario
Compartir con otras webs

'Option Explicit
Option Base 1

Public Sub VENTAS_SECCION_MES()

Dim SheetName As String
Dim strConectar As String
Dim ws As Worksheet
Dim wb As Workbook
Dim Cmd As ADODB.Command
Dim Rs As ADODB.Recordset

Application.ScreenUpdating = False
Sheets("Ventas").Select
'Range("C5").Select



    Application.Cursor = xlWait


    SheetName = "Ventas"

    Set wb = ActiveWorkbook

    Set ws = wb.ActiveSheet
    ws.Name = SheetName


    ' Poner los datos particulares de la conexión

    Dim Con As New ADODB.Connection

    Con.Open "provider=IBMDA400;data source=172.16.1.1;Default Collection=-----;USER ID=---;PASSWORD=------;"
'      Dim Con As New ADODB.Connection
'     strConectar = ThisWorkbook.Path & "\BDVentas.mdb"
'      With Con
'   .ConnectionString = _
'      "Provider=Microsoft.ACE.OLEDB.12.0"
'   .Open "Provider=Microsoft.Jet.OLEDB.4.0; " & _
'     "Data Source=" & strConectar & ";" & _
'     "Jet OLEDB:Database Password=Ventas"
'   End With


 Set ws = Worksheets(SheetName)

 Set Rs = New ADODB.Recordset
    Rs.Open "PRESUPUESTO_VENTAS", Con, adOpenKeyset, adLockOptimistic, adCmdTableDirect

' Me trae el dato de la Consulta SQL
'ActiveCell.CopyFromRecordset Rs

        'LimpiaRango
    ws.Range("C5:C18").ClearContents

    Rs.MoveFirst
    Do While Not Rs.EOF
        dFecha = Rs.Fields(12) 'Año
        wsFecha = Val(ws.Range("C2"))
        dCentro = Rs.Fields(2) 'Centro
        wsCentro = Val(ws.Range("A3"))
        dSeccion = Rs.Fields(5) 'Seccion
        
        dMes = Rs.Fields(15) 'Mes
        wsMes = Val(Range("C3"))
        
        For I = 5 To 18
        wsSeccion = Val(Range("A" & I))
        If dSeccion = wsSeccion And dMes = wsMes Then
            If dFecha = wsFecha And dCentro = wsCentro Then
                If Val(ws.Range("A" & I)) = Rs.Fields(5) Then
                   Valor = Val(ws.Range("C" & I)) + Rs.Fields(9)
                   ws.Range("C" & I) = Valor
                End If
                    
               
            End If
        End If
        Next I
    Rs.MoveNext
    Loop

Con.Close
Set Rs = Nothing
Set Con = Nothing
Set wb = Nothing
Set ws = Nothing




Application.Cursor = xlDefault
Application.ScreenUpdating = True
End Sub

Hola a todos, revisa este código adjunto, lo he corrido en un archivo de access. Tienes que ver como esta su base de datos los campos afectados deben ser números.

Enlace a comentario
Compartir con otras webs

Buenas de nuevo, me da fallo pero entiendo que es porque algo estoy haciendo mal.

imagen.thumb.png.103f8de13773100491af9d3b5b1db9b1.png

 

Creo que para mi sería más fácil trabajarlo sobre la estructura del módulo que tenía inicialmente. Tener en cuenta que me estoy metiendo ahora en este tipo de programación (atacar desde excel bbdd ) y estoy muy verde.

Muchas gracias y disculpar

Enlace a comentario
Compartir con otras webs

'Option Explicit
Option Base 1

Public Sub VENTAS_SECCION_MES()

Dim sql As String, SheetName As String
Dim AÑO, CENTRO, SECCION, MES As String
Dim strConectar As String
Sheets("Ventas").Select
Range("C5").Select
Application.ScreenUpdating = False

    AÑO = Range("C2").Value
    CENTRO = Range("A3").Value
    MES = Range("C3").Value
    SECCION = ActiveCell.Offset(0, -2).Value
    
    'Application.Cursor = xlWait
    Dim wb As Workbook, ws As Worksheet
    
    'Venta de un año, un mes, una tienda y una sección

    sql = "SUM[TOT_VENTAS]) AS TOTAL_VENTAS FROM PRESUPUESTO_VENTAS WHERE,[ANYO] = 'AÑO'), AND ([COD_CC] = 'CENTRO'), AND ([SECCION] = 

   
    SheetName = "Ventas"
    
    Set wb = ActiveWorkbook
    
    Set ws = wb.ActiveSheet
    ws.Name = SheetName
    
    
    ' Poner los datos particulares de la conexión
    
    Dim Con As New ADODB.Connection
    Con.Open "provider=IBMDA400;data source=172.16.1.1;Default Collection=-----;USER ID=---;PASSWORD=------;"
    
    DownloadQuery Con, sql, SheetName
    

    
    Con.Close



Set Con = Nothing
Set wb = Nothing
Set ws = Nothing

Application.Cursor = xlDefault
Application.ScreenUpdating = False
End Sub


Private Sub DownloadQuery(Con As ADODB.Connection, sql As String, SheetName As String)

Dim Cmd As ADODB.Command
Dim Rs As ADODB.Recordset

Set Cmd = New ADODB.Command
Set Cmd.ActiveConnection = Con
Cmd.CommandText = sql

Dim ws As Worksheet, fld As ADODB.Field

Set ws = Worksheets(SheetName)

'Set Rs = Cmd.Execute()
        
Set Rs = New ADODB.Recordset
    Rs.Open "PRESUPUESTO_VENTAS", Con, adOpenKeyset, adLockOptimistic, adCmdTableDirect

' Me trae el dato de la Consulta SQL

'ActiveCell.CopyFromRecordset Rs
        'LimpiaRango
    ws.Range("C5:C18").ClearContents

    Rs.MoveFirst
    Do While Not Rs.EOF
        dFecha = Rs.Fields(12) 'Año
        wsFecha = Val(ws.Range("C2"))
        dCentro = Rs.Fields(2) 'Centro
        wsCentro = Val(ws.Range("A3"))
        dSeccion = Rs.Fields(5) 'Seccion
        
        dMes = Rs.Fields(15) 'Mes
        wsMes = Val(Range("C3"))
        
        For I = 5 To 18
        wsSeccion = Val(Range("A" & I))
        If dSeccion = wsSeccion And dMes = wsMes Then
            If dFecha = wsFecha And dCentro = wsCentro Then
                If Val(ws.Range("A" & I)) = Rs.Fields(5) Then
                   Valor = Val(ws.Range("C" & I)) + Rs.Fields(9)
                   ws.Range("C" & I) = Valor
                End If
                    
               
            End If
        End If
        Next I
    Rs.MoveNext
    Loop


Set fld = Nothing
Set Rs = Nothing

End Sub

Hola, trata de declarar las variables.

Enlace a comentario
Compartir con otras webs

Saludos @ArmandoR, prueba asi

Option Explicit
Option Base 1

Public Sub VENTAS_SECCION_MES()

    Dim sql As String, SheetName As String
    Dim AÑO, CENTRO, SECCION, MES As String
    
    Sheets("Ventas").Select
    
    AÑO = Range("C2").Value
    CENTRO = Range("A3").Value
    MES = Range("C3").Value
    
    Application.Cursor = xlWait
    Dim wb As Workbook, ws As Worksheet
    
    'Venta de un año, un mes, una tienda y una sección
    sql = _
    "SELECT SECCION, SUM(TOT_VENTAS) AS TOTAL_VENTAS " & _
      "FROM PRESUPUESTO_VENTAS " & _
     "WHERE ANYO = " & AÑO & " AND COD_CC = " & CENTRO & " AND MES = " & MES & " " & _
     "GROUP BY SECCION"
    
    SheetName = "Ventas"
    
    Set wb = ActiveWorkbook
    
    Set ws = wb.ActiveSheet
    ws.Name = SheetName
    
    
    ' Poner los datos particulares de la conexión
    
    Dim Con As New ADODB.Connection
    Con.Open "provider=IBMDA400;data source=172.16.1.1;Default Collection=-------;USER ID=-----;PASSWORD=-------;"
    
    
    DownloadQuery Con, sql, SheetName
    
    Con.Close

    Set Con = Nothing
    Set wb = Nothing
    Set ws = Nothing
    
    Application.Cursor = xlDefault

End Sub


Private Sub DownloadQuery(Con As ADODB.Connection, sql As String, SheetName As String)

    Dim Cmd As ADODB.Command
    Dim Rs As ADODB.Recordset
    Dim nFilFin As Double
    Dim rCelda As Range
    Dim nSeccion As Double
    
    Set Cmd = New ADODB.Command
    Set Cmd.ActiveConnection = Con
    Cmd.CommandText = sql
    
    Dim ws As Worksheet, fld As ADODB.Field
    
    Set ws = Worksheets(SheetName)
    
    Set Rs = Cmd.Execute()
    
    nFilFin = ws.Range("A" & Rows.Count).End(xlUp).Row
    
    ' Me trae el dato de la Consulta SQL
    
    Do While Not Rs.EOF
        nSeccion = Rs.Fields("SECCION") 'Seccion
        
        For Each rCelda In ws.Range("A5:A" & nFilFin)
            If CDbl(rCelda.Value) = nSeccion Then
                rCelda.Offset(0, 2).Value = Rs.Fields("TOTAL_VENTAS")
                Exit For
            End If
        Next
        Rs.MoveNext
    Loop
    
    
    Set fld = Nothing
    Set Rs = Nothing

End Sub

el cambio lo realice sobre tu codigo del primer mensaje, recuerda que sin la base de datos es mas complicado, en esencia es lo mismo, realizas la consulta agrupando por SECCION y luego simplemente buscas cada SECCION en la tabla y colocas su total

 

Enlace a comentario
Compartir con otras webs

Archivado

Este tema está ahora archivado y está cerrado a más respuestas.

  • 97 ¿Te parecen útiles los tips de las funciones? (ver tema completo)

    1. 1. ¿Te parecen útiles los tips de las funciones?


      • No
      • Ni me he fijado en ellos

  • Ayúdanos a mejorar la comunidad

    • Donaciones recibidas este mes: 0.00 EUR
      Objetivo: 130.00 EUR
  • Archivos

  • Estadísticas de descargas

    • Archivos
      177
    • Comentarios
      90
    • Revisiones
      27

  • Crear macros Excel

  • Mensajes

    • Buenas a todos, trato de transponer o pivotar el archivo que adjunto. El archivo tiene 3 columnas ( en este caso, como pueden ser más 😞 Cód.artículo, Cód.características y Valor. El objetivo es dejar como primera columna el Cód.artículo y como fila de encabezado Cód.características, y luego cruzando datos con Valor. No sé si me he explicado bien Gracias de antemano. Libro1.xlsx
    • Hola que tal amigos programadores por favor me podrían ayudar con una macro que me genere un archivo CSV delimitado por comas, la estructura del archivo CSV no deberá llevar encabezado, los datos del archivo CSV serán obtenidos de la hoja “Datos”. En la columna A: deberá tener la clave clues que se toma de la columna B de la hoja Datos En la Columna B: el Código (son 230 codigos que van del rango G1:IB1 de la hoja datos) En la Columna C: el valor almacenado a su correspondiente al código y clues En la Columna D: el número del mes que se obtendrá de la de la columna E de la hoja Datos En la Columna E: el año que se tomará de la columna F de la hoja de Datos   Son 230 códigos por lo que la macro generará 230 filas por cada clave clues que tenga la hoja Datos En el archivo anexo una hoja llamada CSV para que vean la estructura que tendrá, el archivo CSV estará delimitado por comas   Les agradecería mucho que me ayuden por favor, Dios los bendiga Exportar datos a csv.xlsx
    • Hola buenas tardes.   Debido al trabajo debo estar comparando en un periodo unos archivos dentro de una carpeta o subcarpeta. en base a la fecha de creacion o modificacion.  pero tengo que estar viendo carpeta por carpeta y aveces son varios. Con una macro intente  listar los archivos de cualquier carpeta y subcarpeta, esto activandolo segun la celdaactiva. El problema es que tiene algunos errores. 1. si la carpeta cuenta con subcarpetas me los manda a muchas filas abajo. Mi idea es hoja(Así debe quedar) Que con una macro pueda seleccionar la carpeta desde el buscador y me de la lista de archivos a partir de la fila 6. siendo columna A= fecha de modificación, columna B =Fecha de creación y columna C=Nombre del archivo con hiperlink. Con otro o con la misma macro poder seleccionar otra carpeta y sus subcarpetas, según sea el caso. y me liste a partir de la columna F de la fila 6 Siendo La columna F=Nombre del archivo, columna H=fecha de creación, columna I=ultima modificación   Para así poder acceder y comparar mis archivos, directamente desde excel.   Muchas gracias Mariano       Listar archivos de 2 carpetas para comparar.xlsm
    • Hola buenas, Os presento mis dudas. Tengo un libro  (llamémosle LibroDestino) con dos módulos, uno de definición de variables "ModDef" y otro de inicializacion de esas mismas variables "ModCfg". Necesito que al copiarme una hoja de otro libro(llamémosle LibroOrigen), mediante un procedimiento, sobrescribir el modulo de inicialización de variables del LibroDestino con el  contenido del módulo que hay en el LibroOrigen. Destacar que los dos módulos de cada libro tienen el mismo nombre "ModCfg". Y tienen una única variable llamada "Mensaje". En el LibroDestino tiene el valor "Hola" y en el LibroOrigen el valor "Adiós" Este procedimiento lo realiza perfectamente,  es decir se sobrescribe, pero si en el mismo procedimiento quiero utilizar el nuevo valor de esa variable, me conserva el valor de la variable anterior. Para hacer las comprobaciones he ejecutado un MsgBox al empezar y al acabar el procedimiento, pero en los dos casos me devuelve el valor original del LibroDestino el valor "Hola", cuando mi idea es que al sobrescribir el modulo con el nuevo valor de la variable, el último MsgBox me devuelva el valor "Adios". Mi objetivo es poder tener la inicialización de esas variables en un libro que no sea el de trabajo (LibroDestino), ya que según la hoja que importe puedo requerir que las variables tengan un valor u otro. ¿Por que no me coge en el procedimiento el nuevo valor de la variable? ¿Cómo podría conseguirlo? He tenido que activar en VBA  la referencia Microsoft visual basic for applications extensibility 5.3 desde  Herramientas -> Referencias. Creo que es la única manera de poder trabajar con los módulos desde VBA, aunque si se pudiera de otra manera creo que sería mas óptimo. Mil gracias de antemano, un saludo!         Libro1_Prueba.xlsm Libro2_Prueba.xlsm
    • Agradecido Antoni! Tus sugerencias me ayudaron mucho! Como pudiese hacerte llegar el archivo?
  • Visualizado recientemente

    • No hay usuarios registrado para ver esta página.
×
×
  • Crear nuevo...

Información importante

Echa un vistazo a nuestra política de cookies para ayudarte a tener una mejor experiencia de navegación. Puedes ajustar aquí la configuración. Pulsa el botón Aceptar, si estás de acuerdo.