I've created a button to copy and paste table from one worksheet to another, to the first blank cell in a column. I'd like to add date (cell A19) and name (cell A5) to the other column, with same amount of lines which have been add.
Scheme of the table has been added as a pic, down below is my piece of code. Tried with the offset but didnt work for me
Dim TblToSave As Range
Dim RangeToPaste As Range
Set TblToSave = ThisWorkbook.Worksheets("Sheet1").Range("D22", Range("O22").End(xlDown))
TblToSave.Copy
ThisWorkbook.Worksheets("db").Activate
Set RangeToPaste = ThisWorkbook.Worksheets("Db").Range("C" & Rows.Count).End(xlUp).Offset(1)
RangeToPaste.PasteSpecial xlPasteValues
I managed to figure it out, this one was known by me but I dont know if it is the best way, the most optimal, not burden for workbook
Dim Lastrow As Integer
Lastrow = ThisWorkbook.Worksheets("db").Cells(Rows.Count, 3).End(xlUp).Row
For Each cell In ThisWorkbook.Worksheets("db").Range("C2:C" & Lastrow)
If Not IsEmpty(cell) AND IsEmpty (cell.Offset(,-1)) Then
cell.Offset(, -1).Value = ThisWorkbook.Worksheets("Sheet1").Range("A5").Value
cell.Offset(, -2).Value = ThisWorkbook.Worksheets("Sheet1").Range("A20").Value
End If
Next
Unfortunately it amends the data from each row, as expected. I need to add it to Offset(,-1) and Offset(,-2) only for new entries (so copied and pasted), the previous stays as they are
Related
I've been trying to figure this out for ages. I've found an answer on StackOverflow but I get object error when trying to use it. I want to copy a set of data from a sheet based on a condition and then paste it in the next empty cell in a column on another sheet. This is my code:
Public list As Worksheet
Public bsawt As Worksheet
Sub Check2()
Set bsawt = Sheets("BSAW_TABLE")
Set list = Sheets("LIST")
lastrow = list.Cells(Rows.Count, "K").End(xlUp).Row
For x = 13 To lastrow
If list.Range("K" & x).Value = "BSAW" Then list.Range("L" & x).Copy Destination:=bsawt.Range("A1").End(xlDown).Offset(1, 0)
Next x
End Sub
If you have nothing in column A, or an entry in A1 only, then copying to this destination
Destination:=bsawt.Range("A1").End(xlDown).Offset(1, 0)
is equivalent to going to the last cell in column A in the worksheet and then attempting to go down one further row, which is clearly an impossibility. See also #PEH's comment.
Instead, work up from the bottom.
Destination:=bsawt.Range("A" & rows.count).End(xlup).Offset(1, 0)
I have a macro that exactly copies one sheet's data into another.
Sub QuickViewRegMgmt()
("Reg Management").Select
Cells.Select
Selection.Copy
Sheets("Quick View Reg Mgmt").Select
Cells.Select
ActiveSheet.Paste
End Sub
I would like for this macro to also go to the last non-blank cell in Column C (or first blank, I really don't care either way). I tried simple end/offset code, e.g.
Range("A1").End(xldown).Offset(1,0).Select
My problem, however, is that the direct copy macro also copies the underlying formulas, which for Column C is an IF formula. Therefore, no cell in the column is actually empty, but rather they all have an IF formula resulting in a true/false value (respectively, a "" or VLOOKUP).
=IF(VLOOKUP('Reg Management'!$Y260,'Reg Guidance'!$A:$V,3,FALSE)=0,"",VLOOKUP('Reg Management'!$Y260,'Reg Guidance'!$A:$V,3,FALSE))
That means the end/offset code goes to the last cell in the column with the formula (C1000) instead of going to the first cell that has a value of "" (which is currently C260).
What code can I add to this macro to select the first cell that contains an IF formula resulting in a value of "" ---- which has the appearance of being blank?
After trying to be fancy with SpecialCells(), or using Find() or something I couldn't get it ...so here's a rather "dirty" way to do it:
Sub test()
Dim lastRow As Long, lastFormulaRow As Long
lastRow = Range("A" & Rows.Count).End(xlUp).Row
Dim i As Long
For i = lastRow To 1 Step -1
If Cells(i, 1).Formula <> "" And Cells(i, 1).Value = "" Then
lastFormulaRow = i
Exit For
End If
Next i
End Sub
Edit2: Here's one using .SpecialCells(). Granted I think we can whittle this down more, I like it better:
Sub lastRow()
Dim tempLastRow As Long
tempLastRow = Range("C" & Rows.Count).End(xlUp).Row
Dim lastRow As Range
Set lastRow = Columns(3).SpecialCells(xlCellTypeFormulas).Find(What:="", LookIn:=xlValues, LookAt:=xlWhole, searchdirection:=xlPrevious, after:=Range("C" & tempLastRow))
Debug.Print lastRow.Row
End Sub
It returns 10 as the row.
Edit: Be sure to add the sheet references before Range() and Cells() to get the last row. Otherwise, it's going to look at your active sheet to get the info.
I am currently facing an issue in which my 'for each' loop is not moving onto subsequent cells for each cell in the range I have defined when I try to execute the script. The context around the data is below:
I have 3 columns of data. Column L contains employees, Column K contains managers, and column J contains VPs. Column K & J containing managers and VPs are not fully populated - therefore, I would like to use a VBA script & Index Match to populate all the cells and match employees to managers to VPs.
I have created a reference table in which I have populated all the employees to managers to directors and have named this table "Table 4". I am then using the VBA code below to try and run through each cell in column K to populate managers:
Sub FillVPs()
Dim FillRng As Range, FillRng1 As Range, cell As Range
Set FillRng = Range("J2:J2000")
Set FillRng1 = Range("K2:K2000")
For Each cell In FillRng1
If cell.Value = "" Then
ActiveCell.Formula = _
"=INDEX(Table4[[#All],[MGRS]], MATCH(L583,Table4[[#All],[EMPS]],0))"
End If
Next cell
End Sub
I feel that something is definitely wrong with the index match formula as the match cell "L583" is not moving to the next cell each time it runs through the loop; however, I am not sure how to fix it. I also do not know what else is potentially missing. The code currently executes, but it stays stuck on one cell.
Any help is greatly appreciated, and I will make sure to clarify if necessary. Thank you in advance.
The problem is that you are only setting the formula for the ActiveCell.
ActiveCell.Formula = _
"=INDEX(Table4[[#All],[MGRS]], MATCH(L583,Table4[[#All],[EMPS]],0))"
This should fix it
cell.Formula = _
"=INDEX(Table4[[#All],[MGRS]], MATCH(L583,Table4[[#All],[EMPS]],0))"
You'll probably need to adjust L583. It will not fill correctly unless you are filling across all cell.
These ranges should probably be changed so that they are dynamic.
Set FillRng = Range("J2:J2000")
Set FillRng1 = Range("K2:K2000")
You should apply the formula to all the cells in the range
Range("K2:K2000").Formula = "=INDEX(Table4[[#All],[MGRS]], MATCH(L2,Table4[[#All],[EMPS]],0))"
UPDATE: Dynamic Range
Every table in Excel should have at least one column that contain an entry for every record in the table. This column should be used to define the height of the Dynamic Range.
For instance if Column A always has entries and you want to create a Dynamic Range for Column K
lastrow = Range("A" & Rows.Count).End(xlUp).Row
Set rng1 = Range("K2:K" & lastrow)
Or
Set rng1 = Range("A2:A" & Rows.Count).End(xlUp).Offset(0, 10)
UPDATE:
Use Range.SpecialCells(xlCellTypeBlanks) to target the blank cells. You'll have to add an Error handler because SpecialCells will throw an Error if no blank cells were found.
On Error Resume Next
Set rng1 = Range("A2:A" & Rows.Count).End(xlUp).Offset(0, 10).SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If rng1 Is Nothing Then
MsgBox "There were no Blank Cels Found", vbInformation, "Action Cancelled"
Exit Sub
End If
The "L583" was not changing because you were not telling it to. The code below should change the reference as the cell address changes.
Range.Address Property
Sub FillVPs()
Dim FillRng As Range, FillRng1 As Range, cell As Range
Set FillRng = Range("J2:J2000")
Set FillRng1 = Range("K2:K2000")
For Each cell In FillRng1
If cell.Value = "" Then
cell.Formula = _
"=INDEX(Table4[[#All],[MGRS]], MATCH(" & cell.Offset(0,1).Address() & ",Table4[[#All],[EMPS]],0))"
End If
Next cell
End Sub
I'm new to vba and need a little help. I have a sheet named "Archive" which will have 12 sets of data displayed/structured in somewhat of a table format. My goal is to pull data from other sheets within the same workbook and paste it in a specific range that corresponds to the appropriate "table" for that data. Here is my code for data that is being pulled from a sheet named "Daily DB" and is being pasted to the "Archive" sheet.
Sub GetDailyDataByWeek()
Dim cw As Integer ' current week
Dim lr As Long 'last row of data
Dim i As Long ' row counter
'Clear exsisting contents
Worksheets("Archive").Range("A5:E11").ClearContents
'Get week number and year of current date
cw = Format(Date, "ww")
With Worksheets("Daily DB")
' Find last row of data
lr = .Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
For i = 2 To lr
If Format(.Cells(i, 1).Value, "ww") = cw Then
.Range(.Cells(i, 1), .Cells(i, 5)).Copy
Worksheets("Archive").Range("a" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
End If
Next i
End With
Application.CutCopyMode = False
End Sub
This code does what I want it to do. The line that I need help in fixing is:
Worksheets("Archive").Range("a" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
As this line looks for the last row of data, which in my case would be the header row of the 12th table. However, I'd like this particular data to go into the first table which after the header row starts at "A5", but I'm not sure how to go about that. Any and all help is greatly appreciated.
If you want to replicate the data from another cell or range into the same workbook I would use the "Value" method of the Range object, like this:
Worksheets("Archive").Range("A" & i).Value = Worksheets("XXX").Range("Z" & j).Value
By doing it like this you would avoid doing all the copy and paste operations.
If you dont want to specify a Range for each value, you could activate the firs cell of the first row and then "offset" your way through, like this:
Worksheets("Archive").Range("A" & i).Activate
ActiveCell.Value = blah blah blah
ActiveCell.Offset(1, 0).Activate 'If you want to move to the next row (same column)
ActiveCell.Offset(0, 1).Activate 'If you want to move to the next column (Same row)
I am looking to make an excel script that can find and replace data, but for the love of everything I cannot figure out how to write it.
Situation:
A-----------B-----------C
Cat-------Dog------Banana
Dog------Fish------Apple
Fish------Cat-------Orange
So the macro would look at the data in a cell in column B, then look at the adjacent cell in column C, and replace all instances of that data in column A with what if found in C. So the results would be:
A---------------B-----------C
Orange------Dog------Banana
Banana------Fish------Apple
Apple--------Cat-------Orange
But that's not all, I would like it to not change cells in A that already have been changed once! (I'm trying this with changing the background colour)
Any help? I am at a complete loss.
EDIT:
Okay I found out how to do the easy part (replacing), but I cannot find out how to not change cells that already have been changed once. Here is my code:
Sub multiFindNReplace()
Dim myList, myRange
Set myList = Sheets("sheet1").Range("A2:B3") 'two column range where find/replace pairs are
Set myRange = Sheets("sheet1").Range("D2:D5") 'range to be searched
For Each cel In myList.Columns(1).Cells
myRange.Replace what:=cel.Value, replacement:=cel.Offset(0, 1).Value, ReplaceFormat:=True
Next cel
End Sub
As far as I can tell, ReplaceFormat:=True
doesn't do anything ;/ so items that already have been replaced once still are being replaced! Is there a way to somehow make this work?
Here's the answer using your recommendation with color as a one-time limiter:
Sub Replace_Once()
'Find last row using last cell in Column B
LastRow = Range("B" & Rows.Count).End(xlUp).Row
'Clear colors in Column A
Range("A1:A" & LastRow).Interior.ColorIndex = xlNone
'Look at each cell in Column B one at a time (Cel is a variable)
For Each Cel In Range("B1:B" & LastRow)
'Compare the cell in Column B with the Value in Column A one at a time (C is a variable)
For Each C In Range("A1:A" & LastRow)
'Check if the Cell in Column A matches the Cell in Column B and sees if the color has changed.
If C.Value = Cel.Value And C.Interior.Color <> RGB(200, 200, 200) Then
'Colors the cell
C.Interior.Color = RGB(200, 200, 200)
'Updates the value in Column A with the cell to the right of the Cell in Column B
C.Value = Cel.Offset(0, 1).Value
End If
Next
Next
'Uncomment the line below to remove color again
'Range("A1:A" & LastRow).Interior.ColorIndex = xlNone
End Sub