Loop through worksheets and set values - vba

I am writing the Sheet names and assigning progress in front of it (adjacent cell) from that sheet.
Suppose sheet name is sheet1, sheet2 ...
I am trying to write
Sheet1 B50 of sheet1
Sheet2 B50 ofsheet2
Sub LoadSummarySheet()
Dim row, i, col As Integer
row = 5
col = 3
Range("C5:C15").ClearContents
For i = 1 To Sheets.Count
If Application.Sheets(i).Name <> "TRACKER" And Application.Sheets(i).Name <> "Sheet1" And Application.Sheets(i).Name <> "PROGRESS" Then
Cells(row, col).Value = Application.Sheets(i).Name
row = row + 1
Range(Cells(row, col + 1)).Value = Application.Sheets(i).Range("B50").Value
End If
Next

maybe you're after something like this (explanations in comments)
Sub LoadSummarySheet()
Dim row As Long, col As Long
row = 5
col = 3
Range("C5:C15").ClearContents
Dim forbiddenNames As String
forbiddenNames = "TRACKER,Sheet1,Sheet2,PROGRESS" 'list sheet names you don't want to be processed
Dim sht As Worksheet
For Each sht In Worksheets 'loop through currently active workbook sheets
If InStr(forbiddenNames, sht.Name) = 0 Then 'if current sheet name is not "forbidden"
Cells(row, col).Value = sht.Name
row = row + 1
Cells(row, col + 1).Value = sht.Range("B50").Value
End If
Next
End Sub
all this assumes that the macro is being run when Summary Sheet is the active one
if this can be not the case then you can assure to write in the proper sheet as follows:
Sub LoadSummarySheet()
Dim row As Long, col As Long
row = 5
col = 3
Range("C5:C15").ClearContents
Dim forbiddenNames As String
forbiddenNames = "TRACKER,Sheet1,Sheet2,PROGRESS" 'list sheet names you don't want to be processed
Dim sht As Worksheet
With Worksheets("TRACKER") ' reference wanted "summary" sheet (change TRACKER" to your actually "summary" sheet name)
For Each sht In Worksheets 'loop through currently active workbook sheets
If InStr(forbiddenNames, sht.Name) = 0 Then 'if current sheet name is not "forbidden"
.Cells(row, col).Value = sht.Name ' preface a dot (.) to reference referenced object (i.e. 'Worksheets("TRACKER")' in this case)
row = row + 1
.Cells(row, col + 1).Value = sht.Range("B50").Value ' preface a dot (.)
End If
Next
End With
End Sub

Related

VBA: How can i select the cell in a row which matches a variable's value?

I have 2 sheets. Sheet1 has 2 rows: column names and values.
Sheet 2 is a master sheet with all the possible column names in. I need to copy the values from sheet 1 into their appropriate column.
I think i can do this via a match function, and so far i have this:
Sub dynamic_paste()
Dim Columnname As String
Dim inputvalue As String
Dim starter As Integer
Dim i As Integer
starter = 0
For i = 1 To 4
'replace 4 with rangeused.rows.count?
Sheets("sheet1").Select
Range("a1").Select
ActiveCell.Offset(0, starter).Select
Columnname = ActiveCell
'sets columnname variable
ActiveCell.Offset(1, 0).Select
inputvalue = ActiveCell
'sets inputname variable
Sheets("sheet2").Select
'**Cells(0, WorksheetFunction.Match(Columnname, Rows(1), 0)).Select**
Range("a1").Offset(1, starter).Value = inputvalue
'inputs variable in the next cell along
starter = starter + 1
Next
End Sub
I need to find out how to use my columnname variable as the matching value, and then offset down to the first row that is empty - then change the value of that cell to the variable called inputvalue.
For extra points: I need to make sure the code doesnt break if they dont find a matching value, and if possible put any values that dont match into the end of the row?
What about this:
Dim LR As Long, X As Long, LC As Long, COL As Long
Dim RNG As Range, CL As Range
Option Explicit
Sub Test()
LR = Sheets(2).Cells.SpecialCells(xlCellTypeLastCell).Row 'Get last used row in your sheet
LC = Sheets(2).Cells(1, Sheets(2).Columns.Count).End(xlToLeft).Column 'Get last used column in your sheet
Set RNG = Sheets(2).Range(Sheets(2).Cells(1, 1), Sheets(2).Cells(1, LC))
'Loop through all the columns on your sheet with values
For X = 1 To Sheets(1).Cells(1, Sheets(1).Columns.Count).End(xlToLeft).Column
Set CL = RNG.Find(Sheets(1).Cells(1, X).Value, lookat:=xlWhole)
If Not CL Is Nothing Then
COL = CL.Column
Sheets(2).Cells(LR + 1, COL).Value = Sheets(1).Cells(2, X).Value 'Get the value on LR offset by 1
Else
Sheets(2).Cells(1, Sheets(2).Cells(1, Sheets(2).Columns.Count).End(xlToLeft).Column).Value = Sheets(1).Cells(1, X).Value
Sheets(2).Cells(LR + 1, Sheets(2).Cells(1, Sheets(2).Columns.Count).End(xlToLeft).Column).Value = Sheets(1).Cells(2, X).Value
End If
Next X
End Sub
This way you will avoid using select. Which is very recommandable!
This is Sheet1:
This is Sheet2:
This is the code:
Option Explicit
Sub DynamicPaste()
Dim col As Long
Dim wks1 As Worksheet: Set wks1 = Worksheets(1)
Dim wks2 As Worksheet: Set wks2 = Worksheets(2)
For col = 1 To 3
Dim currentRow As Long
currentRow = WorksheetFunction.Match(wks2.Cells(1, col), wks1.Columns(1))
wks2.Cells(2, col) = wks1.Cells(currentRow, 2)
Next col
End Sub
This is Sheet2 after the code:
This is a must-read - How to avoid using Select in Excel VBA

VBA. Replace a table cell content based on match from another table or delete entire row if match is not found

I am trying to make the following to work:
There are two tables in a separate worksheets. I want it to check each cell in worksheet2 column B and find a match from worksheet1 column A. If a match is found then replace the data in worksheet2 column B with a data from a matching row of worksheet1 column B.
If a match is not found from a worksheet1 column A then delete entire row in a worksheet2 column B.
Sub match_repl_del()
Dim r1 As Long, rfound, vfound
Dim w1, w2, v As Long
Set w1 = Sheets(3) ' data sheet
Set w2 = Sheets(2) ' target sheet
r1 = 2 'data starting from row 2
Do While Not IsEmpty(w1.Cells(r1, 1))
v = w1.Cells(r1, 1)
rfound = Application.Match(v, w2.Columns(2), 0) ' look for value
If Not IsError(rfound) Then ' found it?
vfound = w2.Cells(rfound, 2)
If w1.Cells(r1, 2) <> vfound Then ' if value does not match sheet1 column b
w2.Cells(rfound, 2) = w1.Cells(r1, 2) ' update based on origin sheet
lastC = w2.Cells(rfound, 1).End(xlToRight).Column
w2.Range(w2.Cells(rfound, 1), w2.Cells(rfound, lastC)).Interior.ColorIndex = 5
Else ' delete entire row on sheet2 if match is not found
w2.Rows(r1).EntireRow.Delete
End If
End If
r1 = r1 + 1
Loop
End Sub
Try this wat, it's work for me :
Option Explicit
Sub test()
' Active workbook
Dim wb As Workbook
Set wb = ThisWorkbook
Dim i As Long
Dim j As Long
'*******************************************
'Adapt this vars
'define your sheets
Dim ws_1 As Worksheet
Dim ws_2 As Worksheet
Set ws_1 = wb.Sheets("Sheet1") 'find a match in worksheet1 column A
Set ws_2 = wb.Sheets("sheet2") 'cell in worksheet2 column B
'definie the last Rows
Dim lastRow_ws1 As Long
Dim lastRow_ws2 As Long
lastRow_ws1 = ws_1.Range("A" & Rows.Count).End(xlUp).Row 'if you need, adjust column to find last row
lastRow_ws2 = ws_2.Range("B" & Rows.Count).End(xlUp).Row 'if you need, adjust column to find last row
'*******************************************
For i = lastRow_ws2 To 2 Step -1
For j = 1 To lastRow_ws1
Dim keySearch As String
Dim keyFind As String
keySearch = ws_2.Cells(i, 2).Value
keyFind = ws_1.Cells(j, 1).Value
If keySearch = keyFind Then
'MsgBox keySearch & " " & keyFind & " yes"
ws_2.Cells(i, 2).Value = ws_1.Cells(j, 2).Value
GoTo next_i
End If
Next j
ws_2.Rows(i).EntireRow.Delete
next_i:
Next i
End Sub

Searching multiple cells in multiple worksheets and then copying another cells value in a summary sheet

I have a workbook that has 4 worksheets all of which have dates on row 5, stating at column D. In the cell next to the date the person will put either 'ET','LT','EG','1ET', '2LT' or they will leave it blank.
I am reading on how VBA works at the moment but I have just started so very new to this.
I have this so far:
Sub test()
Dim summarySheet As Worksheet
Dim sh As Worksheet
Dim j As Integer
'change "Summary" to the sheet name that is true for you'
Set summarySheet = ThisWorkbook.Worksheets("Summary")
'number of first row where need to paste in summary sheet'
j = 2
'loop throught all sheets'
For Each sh In ThisWorkbook.Worksheets
If sh.Name <> summarySheet.Name Then
summarySheet.Range("B" & j & ":AF" & j).Value = _
sh.Range("D5:AH5").Value
j = j + 1
End If
Next
End Sub
It displays all the sheets data, but what I need is if there is either ET or LT entered in row 5 next to the date then it adds the corresponding data from row 37 into a summary sheet. If it's just the number then it is to skip that and find the next ET or LT
EG
Sheet 1
Row 5 1ET 2LT 3ET 4 5 6 7ET 8ET
===========================
Row 37 16 32 2 45 67
Sheet 2
Row 5 1 2 3LT 4ET 5ET 6LT 7 8LT
===========================
Row 37 23 33 13 22 34
SUMMARY SHEET
ET LT
1 16
2 32
3 2 23
4 33
5 13
6
7 45
8 67 34
9
Etc
I don't completely understand what you are trying to do. Your code copies the range exactly to the Summary sheet, but it looks like the result you want transposes them - has the numbers/dates running down the rows instead of across the rows. Also, you say "dates" but have the numbers 1-9 on the Summary Sheet and have the numbers 1-9 on your Sheet1 and Sheet2. I also cannot tell which column the "corresponding" values in row 37 are.
Therefore, this code may not exactly work for you as it based on the assumptions that 1) you do NOT want D5:AH5 from each sheet pasted exactly onto the Summary sheet; 2) since they are the only ones you mention as criteria, "ET" and "LT" are the only codes next to "dates" you care about; 3) the value in row 37 is in the same column as the "date"; 4) the "1ET" and "2LT" in your data represent a "1" in D5, "ET" in E5, "2" in F5, "LT" in G5, and so on; 5) since you used the numbers 1-9, the row for pasting the value from row 37 is determined by taking the "date" and adding 1. If you have actual dates, you will need to change your logic for pasteRow.
Sub test()
Dim summarySheet As Worksheet
Dim sh As Worksheet
Dim searchRng As Range
Dim dateCell As Range
Dim pasteCol As Integer
Dim copyRow As Integer
Dim pasteRow as integer
'change "Summary" to the sheet name that is true for you'
Set summarySheet = ThisWorkbook.Worksheets("Summary")
'the "corresponding row" to copy
copyRow = 37
'loop throught all sheets'
For Each sh In ThisWorkbook.Worksheets
If sh.Name <> summarySheet.Name Then
'set the range that we are using
Set searchRng = sh.Range("D5:AH5")
For Each cell In searchRng
'loop through the range and check if it has the desired key value
If cell.Value = "ET" Or cell.Value = "LT" Then
'set which column on SummarySheet will get the value
If cell.Value = "ET" Then
'column B, ie column #2
pasteCol = 2
ElseIf cell.Value = "LT" Then
'column C, ie column #3
pasteCol = 3
End If
'set the cell containing the date - assumes is to the left of our key value cell
Set dateCell = cell.Offset(0, -1)
'set row # to paste to, ie if the value in dateCell is 9, then paste to row 10
pasteRow = dateCell.Value + 1
'set the value on summarySheet using the value in dateCell + 1 for our row number
'and dateCell's column with copyRow to get our "corresponding" value
summarySheet.Range(Cells(pasteRow, pasteCol).Address).Value = _
sh.Range(Cells(copyRow, dateCell.Column).Address)
End If
Next cell
End If
Next
End Sub
EDITED based on new information from actual spreadsheet:
Sub test()
Dim summarySheet As Worksheet
Dim sh As Worksheet
Dim searchRng As Range
Dim dateNum As Integer
Dim pasteCol As Integer
Dim copyRow As Integer
Dim pasteRow As Integer
Dim c As Range
Dim oldVal As Integer
'change "Summary" to the sheet name that is true for you'
Set summarySheet = ThisWorkbook.Worksheets("Summary")
'clear current value on summarySheet
summarySheet.Range("C3:D33").Value = ""
'loop throught all sheets'
For Each sh In ThisWorkbook.Worksheets
If sh.Name <> summarySheet.Name Then
'set the range that we are using
Set searchRng = sh.Range("D5:AH5")
'the "corresponding row" to copy
With sh.Range("C:C")
Set c = .Find("Number of staff")
If Not c Is Nothing Then
copyRow = c.Row
End If
End With
For Each cell In searchRng
'loop through the range and check if it has the desired key value
If cell.Value Like "*ET" Or cell.Value Like "*LT" Then
'set which column on SummarySheet will get the value
If cell.Value Like "*ET" Then
'column C, so column #3
pasteCol = 3
ElseIf cell.Value Like "*LT" Then
'column D, so column #4
pasteCol = 4
End If
'get the date from the cell
dateNum = Val(cell.Value)
If dateNum = 0 Then
MsgBox "Sheet " & sh.Name & " cell " & cell.Address & " is missing date. Please fill in and run again."
Exit Sub
End If
'set row # to paste to, ie if the value in dateCell is 9, then paste to row 11
pasteRow = dateNum + 2
'set the value on summarySheet using cell's column with copyRow to get our "corresponding" value
oldVal = summarySheet.Range(Cells(pasteRow, pasteCol).Address).Value
summarySheet.Range(Cells(pasteRow, pasteCol).Address).Value = _
sh.Range(Cells(copyRow, cell.Column).Address).Value + oldVal
End If
Next cell
End If
Next
MsgBox "Complete"
End Sub
Option Explicit
Private Sub Worksheet_Activate()
Dim r As Range, rng As Range, snRow As Range, x As Integer
ActiveSheet.Range("C4:AG5").ClearContents
For x = 1 To Sheets.Count
If Sheets(x).Name <> "Summary" Then
With Sheets(Sheets(x).Name)
With .Range("C:C")
Set snRow = .Find("Number of staff", LookIn:=xlValues, lookat:=xlWhole)
End With
Set rng = .Range("D5", "AH5")
For Each r In rng
If InStr(1, r.Value, "LT") > 0 Then
Sheets("Summary").Cells(5, r.Column - 1) = .Cells(snRow.Row, r.Column).Value
ElseIf InStr(1, r.Value, "ET") > 0 Then
Sheets("Summary").Cells(4, r.Column - 1) = .Cells(snRow.Row, r.Column).Value
End If
Next
End With
End If
Next
End Sub
This achieves everything I wanted with the summary sheet going across the page instead of vertically.

How to only copy cells that have data from one sheet to another and not leave blanks in between

I have a workbook with 4 worksheets and Sheet4 (titled "Deficiency List") is populated in 'column B' with values from other sheets based on different criteria. The list begins with "B1" and goes to "B1155". I would like to only copy the cells that have data in them and not the blanks to Sheet3 (titled "Deficiencies") starting at cell "B12".
Example, if there is only data on Sheet4 in cells: B3, B36, B756 and B1005, those would be copied to Sheet3 into cells: B12, B13, B14 and B15.
Here is the code I have to copy the data but it doesn't eliminate the blanks.
Sub Copy_Values()
Dim i As Long
Sheets("Deficiency List").Select
iMaxRow = 1155
For iRow = 1 To iMaxRow
With Worksheets("Deficiency List").Cells(iRow, 2)
' Check that cell is not empty.
If .Value = "" Then
'Nothing in this cell.
'Do nothing.
Else
' Copy the cell to the destination
Worksheets("Deficiencies").Cells(iRow + 11, 2).Value = .Value
End If
End With
Next iRow
End Sub
If (Trim$(CStr(.Value)) = "") Then
If you don't want rows in output area to be skipped,
declare a Long variable to hold destination row number
initialize it outside the loop to 11
in the else part, increment the variable and then use it as row number instead of irow + 11
Sub Copy_Values()
Dim i As Long, d As Long, shtD, shtDL, tmp
Dim iMaxRow As Long, iRow As Long
Set shtD = Worksheets("Deficiencies")
Set shtDL = Worksheets("Deficiency List")
iMaxRow = 1155
d = 12
For iRow = 1 To iMaxRow
With shtDL.Cells(iRow, 2)
tmp = Trim(.Value)
If Len(tmp) > 0 Then
shtD.Cells(d, 2).Value = tmp
d = d + 1
End If
End With
Next iRow
End Sub

VBA how to loop from the first cell/column (Force it)

Below are my codes, I am trying to force the checking to start from the first cell, but it doesn't work. Can anyone advise me on that. Thanks
I am trying to do checking on the names which is on the 3rd column of Workbook A and compare it with the other column in another workbook. Upon match of the string, it will copy certain cells to the desalinated column
Sub copyandpaste()
Set From_WS = Workbooks("copy_data2").Worksheets("Data")
Set To_WS = Workbooks("Book1").Worksheets("Sheet1")
Dim v1 As String
Dim v2 As String
Dim diffRow As Long
Dim dataWs As Worksheet
Dim copyWs As Worksheet
Dim rowData As Long
Dim totRows As Long
Dim lastRow As Long
Dim result As String
Dim row_no As Integer
Dim Name As Range
Dim Namelist As Range
diffRow = 1 'compare
Set dataWs = Worksheets("Data")
Set copyWs = Worksheets("Diff")
For Each c In Worksheets("Data").Range("C2:C10")
If c.Value <> "" Then
v1 = c
End If
For Each d In Workbooks("Book1").Worksheets("Sheet1").Range("B2:B10")
If d.Value <> "" Then
v2 = d
End If
With From_WS.Cells(1, 2).CurrentRegion
Total_Rows = .Rows.Count
Total_Columns = .Columns.Count
End With
Set mycellA = From_WS.Range("C:C")
Set mycellB = To_WS.Range("B:B")
Copy = False
' With Sheets("copy_data2")
' lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
'find first row
'column1 = Range("A2").End(xlToRight).Column
'For row_no = 1 To 10
'=========================================================================
Set Namelist = dataWs.Range("A1:A" & dataWs.Cells(Rows.Count, "A").End(xlUp).Row)
'Now loop through all the cells in the range
'For Each Name In Namelist.Cells
mynumber = 1
For Each Name In Namelist
'=======================================================================
If v1 = v2 Then
'select sheet
Sheets("Data").Select
'ActiveCell.Select 'select active cell
ActiveCell.Interior.ColorIndex = 36 'color the cell
'copy active cell same row
ActiveCell.Range("A1:F1").Copy
ActiveCell.Interior.ColorIndex = 50 'color the cell
'Paste file destination
Sheets("Diff").Select
Sheets("Diff").Range("A2").Select
'Paste Active
ActiveSheet.Paste
ActiveCell.Interior.ColorIndex = 37 '<< Colored Blue
'==================================================================
'select sheet
Sheets("Data").Select
'ActiveCell.Select 'select active cell
ActiveCell.Interior.ColorIndex = 36 'color cell Yellow
'result = ActiveCell.EntireRow.copy
'copy active cell same row
ActiveCell.Range("H1:J1").Copy
'Paste file destination
Sheets("Diff").Select
'Paste cell destination
Sheets("Diff").Range("G2").Select
'Paste Active
ActiveSheet.Paste
mynumber = mynumber + 1
End If
Next Name
Next d
Next c
End Sub
This is the second function, to count and go through the rows.
Sub RoundToZero1()
For Counter = 1 To 20
Set curCell = Worksheets("Data").Cells(Counter, 3)
If Abs(curCell.Value) < 0.01 Then curCell.Value = 0
Next Counter
End Sub
Update Question:
I have the code below, I need to make the column A to be incremental. Anyone have suggestion how to achieve that?
Sheets("Diff").Range("A").Select
The line Set selectedCell = selectedCell + 1 throws an error when I run it and doesn't appear to do anything in the code, if that is the case you should comment it out or delete it.
Also I think you need to change
Else
If IsEmpty(Cells(i, 1)) = True Then 'if cells in column "A" is empty then stop
to
ElseIf IsEmpty(Cells(i, 1)) = True Then 'if cells in column "A" is empty then stop
As it stands you have an extra open If statement.