Nieoczekiwane zachowanie "Dla każdego wks W aktywnym oknie.Wskazanych w tabeli, ma to wpływ na większą liczbę kolumn, niż powinno być

0

Pytanie

zrobiłem ten kod, który działa całkiem nieźle, za wyjątkiem ostatniej części:

Zachowanie ostatniej części musi być taki ".Wnętrze.Kolor" i ".Wartość zmieniała się do ostatniej wypełnionej kolumny, zamiast tego, on wpływa na pierwszej komórki w wielu innych kolumn. Jakieś pomysły?

  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

Najlepsza odpowiedź

0

Jeśli dobrze rozumiem, do czego dążycie, następujący robi to, co chcesz.

  • Do kodu można było podejść inaczej (i, być może, uczynić go bardziej wydajne), gdyby znany był szerszy kontekst
  • Jednak czuję, że jest to tylko etap w swoim rozwoju, więc trzymaj się swojego podejścia (wszędzie tam, gdzie jest to uzasadnione).
' 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

Uwaga 1: Nie jestem pewien co do powodu, ale twój kod wstawia "kolumny porównania" po każdej kolumny, z wyjątkiem ostatniej kolumny (skopiowanych danych). Jeśli dobrze rozumiem twoje intencje, ja bym zasugerował, że chcesz to zrobić i do ostatniej kolumny. Jeśli to prawda, to:

'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

Uwaga 2: Mój kod zmienia zapis <cell value> & " - Comparison" do wszystkich komórek w każdej kolumnie, aż do ostatniej niepustej komórki w każdym "сравниваемом" kolumnie (wliczając puste komórki powyżej). Jeśli chcesz zrobić ten wpis dla wszystkich wierszy w skopiowanej zakresie danych (niezależnie od tego, puste komórki lub nie), można uprościć kod, umieszczając następujący:

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

I zabierz to:

    ' 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

Inne uwagi / Wskazówki:

  1. Polecam Option Explicit w górnej części wszystkich modułów (po prostu oszczędza dużo czasu na debugowania z powodu literówek)
  2. Nie ma potrzeby (i to nie jest dobrą praktyką) zadeklarować Public zmienne, które są używane tylko lokalnie, w tym Sub lub Function. Zadeklaruj to samo lokalnie (zazwyczaj w górnej części Sub lub Function).
  3. Zaleca się wstępne symbole nazw zmiennych do identyfikacji typu danych. Może być dowolnej długości, ale zwykle wynosi 1, 2 lub 3 znaki (preferencje kodera). na przykład, powyżej użyłem lg do identyfikacji długich typów danych. Podobnie, używam in dla Integer, st dla String, rg dla Range itp.
2021-11-24 07:52:25

Nie jestem pewien, jak powszechnie używana notacja węgierska obecnie, i zawsze toczyły się spory o to, czy to dobrze czy nie. Mam na myśli, że to może być przydatne, po prostu IMO kosztem czytelności (i w pewnym skrócie, który jest wtórne).
Chris Strickland

3) To, że jesteś tu отстаиваете, to systemowy węgierski", który jest powszechnie upadła. Z drugiej strony, "Aplikacje po węgiersku" mogą być pomocne. Dobry odczyt (o vba, ale nadal aktualne)
chris neilsen

@Chris Strickland: Zgadzam się, są za i przeciw. W językach, w których typ danych jest implicite (w porównaniu z wyraźnym), wybieram docelowe nazewnictwo. W językach (na przykład, vba), gdzie to wyraźnie, podtrzymuję "sprawdzonego i zaufanego", ponieważ uważam, że to ułatwia debugowanie.
Spinner

W innych językach

Ta strona jest w innych językach

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