Comportamiento inesperado de "Para Cada una de las semanas En ActiveWindow.SelectedSheets", que afecta a más de la columna que debe ser

0

Pregunta

hice este código que funciona bastante bien excepto la última parte:

El comportamiento de la última parte debe ser que ".Interior.Color" y ".El valor de" afectado hasta el último poblado de la columna, sino que afecta a la primera celda de muchas otras columnas. Alguna idea?

  Sub Sample_Workbook()
        
        'Creation of new workbook
        Application.ScreenUpdating = False        
        Workbooks.Add
        
        Set wb = ActiveWorkbook
        wb.SaveAs ThisWorkbook.Path & "etc.xlsx"
        
        'following variable is declared for sending mail purpose
        SourceWorkbook = ActiveWorkbook.Name
        
        Set this = Workbooks("Sample")
        Set wb = ActiveWorkbook
        Set ws1 = wb.Sheets("Sheet1")
        wb.Sheets.Add After:=Sheets(1)
        Set ws2 = wb.Sheets(2)
        wb.Sheets.Add After:=Sheets(2)
        Set ws3 = wb.Sheets(3)
        ws1.Name = "Sheet1"
        ws2.Name = "Sheet2"
        ws3.Name = "Sheet3"
        
        
        'Model the new excel with the requirements:
        Dim Population, Population2 As Range
        Dim lastRow As Long, firstRow As Long
        Dim sampleSize As Long
        Dim unique As Boolean
        Dim i As Long, d As Long, n As Long
        
        
        'following function perfoms all the calculations and copy and pasting        
            
            doTheJob x, y, z, num, q           
            doTheJob x, y, z, num, q 
            doTheJob x, y, z, num, q 
                
        'copy and paste the remaining sheets from the sample files
            Workbooks.Open ThisWorkbook.Path & "Sample2.xlsx"
                Sheets("Sheetx").Copy After:= _
                 Workbooks(SourceWorkbook).Sheets(6)
            Workbooks("Sample2.xlsx").Close SaveChanges:=False
        
        Application.ScreenUpdating = True
        Application.CutCopyMode = False
        ws1.Select
        wb.Close SaveChanges:=True
        End Sub

'these will make the variable available to all modules of this macro Workbook
Public SourceWorkbook As String
Public this, wb As Workbook
Public data As Range
Public output As Range
Public ws1, ws2, ws3 As Worksheet
Public LastCol As Long
Public wks As Worksheet
Public iCol As Long




'FUNCTION
Sub doTheJob(x As String, y As String, z As String, num As Integer, q As String)

    'beginning logic.
    this.Worksheets(x).Activate

Set Population = Range("a3", Range("a3").End(xlDown))
    sampleSize = this.Worksheets("SNOW Reports").Range(y).Value

Set r = Population
    lastRow = r.Rows.Count + r.Row - 1
    firstRow = r.Row


    For i = 1 To sampleSize
   Do
   
    unique = True
    n = Application.WorksheetFunction.RandBetween(firstRow, lastRow)
    
        For d = 1 To i - 1
        'wb.Sheets(z).Activate
        
          If wb.Sheets(z).Cells(d + 1, 50) = n Then
            unique = False
            Exit For
            End If
        Next d
        
          If unique = True Then
          Exit Do
          End If
        
    Loop
    
    Set data = this.Worksheets(x).Range("a" & n, Range("a" & n).End(xlToRight))
    Set output = wb.Worksheets(z).Range("A" & i + 1)
     
    output.Resize(data.Rows.Count, data.Columns.Count).Value = data.Value
        'THE NEXT LINE IS JUST FOR DELETEING LAST COLUMN PURPOSE
    wb.Worksheets(z).Cells(1, 50) = "REF COL"
    wb.Worksheets(z).Cells(i + 1, 50) = n
    
 this.Worksheets(x).Activate
    
Next i

    'delete REF COL:
       With wb.Sheets(z)
            .Columns(50).Delete
        End With
    
    'copy and paste header:
    Set data = this.Worksheets(x).Range("a2", Range("a2").End(xlToRight))
    Set output = wb.Sheets(z).Range("A1")
    
    output.Resize(data.Rows.Count, data.Columns.Count).Value = data.Value
     
'_________________________________________________________________________________________________________

'copy and paste into new sheet with recorded macro
    
   wb.Activate
   Sheets.Add(After:=Sheets(num)).Name = q
   wb.Worksheets(z).Cells.Copy Destination:=wb.Worksheets(q).Range("A1")
             
    'create columns and add color and text dinamically
    For Each wks In ActiveWindow.SelectedSheets
        With wks
            For iCol = .Cells.SpecialCells(xlCellTypeLastCell).Column To 2 Step -1
                .Columns(iCol).Insert
                With Cells(1, iCol)
                .Interior.Color = 65535
                .Value = Cells(1, iCol - 1) & " - Comparison"
                End With
            Next iCol
        End With
    Next wks

End Sub
excel foreach vba
2021-11-23 21:01:44
1

Mejor respuesta

0

Si entiendo lo que estás intentando hacer, el siguiente hace lo que quiere.

  • El código puede ser abordado de manera diferente (y posiblemente más eficaz), si el contexto era conocido
  • Sin embargo, tengo la sensación de que esto es sólo una etapa en su desarrollo, por lo que se han quedado con su enfoque (siempre que sea razonable).
' I suggest this goes to the top of the sub (no need for public declaration)
' Note the shorthand declaration: 'lgRow&' is the same as `lgRow as Long'
    Dim lgRow&, lgCol&, lgLastRow&
             

' Replaces the code starting with the next comment 
    'create columns and add color and text dynamically
    For Each wks In ActiveWindow.SelectedSheets
        With wks
            For lgCol = .Cells.SpecialCells(xlCellTypeLastCell).Column To 2 Step -1
                
                ' Insert a column (not sure why you're not doing this after the last column also)
                .Columns(lgCol).Insert
                
                ' Get last row with data in the column 1 to the left
                With .Columns(lgCol - 1)
                    lgLastRow = .Cells(.Cells.Count).End(xlUp).Row
                End With
                    
                ' In the inserted column:
                ' o Set cell color
                ' o Set value to corresponding cell to the left, appending ' - Comparison'
                For lgRow = 1 To lgLastRow
                    With .Cells(lgRow, lgCol)
                        .Interior.Color = 65535
                        .Value = .Offset(0, -1) & " - Comparison"
                    End With
                Next lgRow
            Next lgCol
        End With
    Next wks

Nota 1: No estoy seguro de la razón, pero el código se inserta la 'comparación de las columnas' después de cada columna, excepto la última columna (de la copia de datos). Si entiendo tu intención correctamente, yo supongo que usted quiere hacer esto por la última columna también. Si que es cierto:

'change this line
    For lgCol = .Cells.SpecialCells(xlCellTypeLastCell).Column To 2 Step -1
'To:
    For lgCol = .Cells.SpecialCells(xlCellTypeLastCell).Column + 1 To 2 Step -1

Nota 2: Mi código cambios escribir <cell value> & " - Comparison" a todas las celdas de cada columna, hasta el último de los no-celda en blanco en cada una 'comparación' columna (incluyendo las celdas en blanco por encima de eso). Si quieres hacer que escribir para todas las filas de la copia del rango de datos (si las células están en blanco o no) puede simplificar el código mediante la colocación de los siguientes:

' Insert this:
    lgLastRow = .Cells.SpecialCells(xlCellTypeLastCell).Row
'above line:
    For lgCol = ....

Y eliminar este:

    ' Get last row with data in the column 1 to the left
    With .Columns(iCol - 1)
        lgLastRow = .Cells(.Cells.Count).End(xlUp).Row
    End With

Otra Nota / Sugerencias:

  1. Recomendamos Option Explicit en la parte superior de todos los módulos (sólo ahorra una gran cantidad de depuración debido a errores).
  2. No hay necesidad (y no es una buena práctica declarar Public las variables que se utilizan únicamente de forma local en un determinado Sub o Function. En su lugar, declarar mismo local (por lo general en la parte superior de la Sub o Function).
  3. Es una buena práctica utilizar los principales caracteres de los nombres de las variables de IDENTIFICACIÓN del tipo de datos. Puede ser de cualquier longitud, pero es comúnmente de 1, 2 o 3 caracteres (codificador de preferencia). por ejemplo, Anteriormente he utilizado lg para la IDENTIFICACIÓN de los tipos de datos long. Del mismo modo, yo uso in para Integer, st para String, rg para Range, etc.
2021-11-24 07:52:25

No estoy seguro de cómo ampliamente utilizado notación húngara es en la actualidad, y siempre había un debate sobre si era o no una buena cosa. Quiero decir, puede ser útil, sólo de la OMI, en detrimento de la legibilidad (y algunos de la brevedad que es secundario).
Chris Strickland

Re 3) Lo que estamos defendiendo aquí es "sistemas de hungría", que es ampliamente desacreditado. Por otro lado, "Aplicaciones de la húngara" puede ser útil. Una buena lectura (no se trata de vba, pero sigue siendo relevante)
chris neilsen

@Chris Strickland: de acuerdo que hay a favor y en contra. En lenguas donde el tipo de datos es implícito (frente a explícito), puedo optar para el propósito de nomenclatura. En idiomas (como vba) donde es explícita, me quedo con el 'tratado y probado como me parece que hace más fácil depurar.
Spinner

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................