So I've got this Workbook which contains a lot of data. And I've got this one sheet which basically copies the data based on certain conditions.
Each cell in each row looks like this (the last specified cell is the one where the formula is in):
=IF(Numbers1!E2<>0;Numbers1!A2;"")
=IF(Numbers1!E3<>0;Numbers1!A3;"")
=IF(Numbers1!E4<>0;Numbers1!A4;"")
=IF(Numbers1!E2<>0;Numbers1!B2;"")
=IF(Numbers1!E3<>0;Numbers1!B3;"")
=IF(Numbers1!E4<>0;Numbers1!B4;"")
So the formula in cell A2 is the first one, formula in A3 is the second line etc.
I want to copy the value from the same column and row from the sheet Numbers1, IF the value in the same row of column E is not 0. This seems to be working just fine.
But, when I update the data in Numbers1 sheet, the formulas are all of a sudden invalid and the formula now looks like this:
=IF(Numbers1!#REF!<>0;Numbers1!#REF!;"")
Each formula in each cells look identical to the formula above. And I can't have that, why can't Excel just keep the formula as it is without "helping" me?
Since you may be better off using a macro to rewrite your formulas, here are the basics:
Sub RewriteFormulas()
Dim row, col As Integer
row = 1 'row you want your target formulas to be on
For row = 1 To 60
For col = 1 To 13
ActiveSheet.Cells(row, col).Formula = "=IF(Numbers1!" & Cells(row,col).Address & "<>0,Numbers1!" & Cells(row+2,col).Adddress & ","""")"
Next row
Next col
End Sub
You can play around with using different sheets (or different workbooks) instead of just ActiveSheet so you can have 1 workbook that stores the macro and alters data in whatever workbooks provide your updated datasets.
Hope that helps...
Related
I am just starting out with Excel VBA and to be honest I am not that skilled in using normal Excel either.
I've got one sheet that has unique codes in column C, I also have another sheet that has unique codes in column A (except first rows as they've got column labels).
In case this unique code from sheet 1 is also found in the column in sheet 2, I want column J in the sheet1 to have that code value, otherwise, if it cannot be found, I want it to have #N/A.
Normally in Excel I would do this by selecting J2 and entering following function:
=VLOOKUP(C2,Sheet2!A:A,1,False)
Then I'd just double click the corner of the cell to populate all rows.
How do I do it in VBA? I wrote this code hoping it would do something:
Worksheets("Sheet1").Activate
ActiveSheet.Range("J:J").Value = Application.VLookup(C2,Worksheets("Sheet2").Range("A:A"),1,False)
However, this does not work. I just get #N/A for all cells in the J column. Any suggestions what I can do?
The following code will give you what you want. Note that you would only want to put the formula into rows where values actually exist in column C on sheet1.
Option Explicit
Sub InsertVlookup()
Dim LastRow As Long
LastRow = Sheet1.Cells(Rows.Count, 3).End(xlUp).Row
With Sheet1.Range("J2:J" & LastRow)
.FormulaR1C1 = "=VLOOKUP(RC[-7],Sheet2!C[-9],1,FALSE)"
.Value = .Value
End With
End Sub
I'm trying to search on the specific column(E), and if matched with the first 4 digit, I would like to copy the number to a different column.
Column E is where i would like to paste all the random number(dynamic)
Column A/B/C is static where i would add 4 digits from time to time.
Column I/J/K is where is would like to paste the result.
PS:
I'm doing it manually and would really appreciate if someone can help me out with the automation hence no code is provided. :(
Having ExcelO365 means you may use FILTER(). Therefor try the below:
Formula in I2:
=FILTER($E:$E,ISNUMBER(MATCH(--LEFT($E:$E,4),A:A,0)))
Drag right to K2. Now, this is dynamic and will change accordingly upon data entry in column E:E, or changing values in A:C.
this is the code to execute on sheet 1, it goes through the entire column E and validates through the formula of counting if in each of the first three columns and assigns the value found in the corresponding columns.
Sub macro()
Dim Static_Data As String
Dim Sht As Worksheet
Set Sht = ThisWorkbook.Sheets("Hoja1")
Active_row = 2
Do While Sht.Range("E" & Active_row).Value <> ""
Static_Data = Sht.Range("E" & Active_row).Value
For i = 1 To 3
If Application.WorksheetFunction.CountIf(Sht.Columns(i), Mid(Static_Data, 1, 4)) > 0 Then
Sht.Cells(Sht.Cells(Rows.Count, i + 8).End(xlUp).Row + 1, i + 8).Value = Static_Data
End If
Next i
Active_row = Active_row + 1
Loop
End Sub
For Excel versions that don't support FILTER or as an alternative you can use standard formulas for this.
If you use columns F-H as helper columns (and these columns can be hidden) then the formula in F2 will be:
=IF(NOT(ISERROR(VLOOKUP(VALUE(LEFT($E2,4)),A$2:A$100,1,FALSE)))=TRUE,$E2,"")
The formula can then be copied across and down. This will find your matches.
In order to then remove the blanks from the data you can use the following formula in I2 and again copy across and down. Depending on how many numbers you want to add in, you may want to extend the range A$2:A$100 in the top formula and F$2:F$100 in the bottom formula
=IFERROR(INDEX(F$2:F$100,AGGREGATE(15,6,(ROW(F$2:F$100)-ROW(F$2)+1)/(F$2:F$100<>""),ROWS(I$2:I2))),"")
I have compiled wheel data but want a VBA macro that copies any cell from sheet 1 (named: SheetSJ) that matches partial text, and then copies that cell's data into sheet 2. This is to make the data much easier to work with.
Search each row for any cells in SheetJS that contain text "Product ID", if no matches then ignore
If any cell (text) matches, copy that cell, and paste the contents to sheet 2 column B (beginning with row 2)
Search each row for any cells in SheetJS that contain text "Bolt Pattern", if no matches then ignore
If any cell (text) matches, copy that cell, and paste the contents to sheet 2 column D (beginning with row 2)
Wheel Data
As evident in the picture, the data is all over the place in each column and thus the macro cannot use any particular cell for reference. It can only match text values (which are unique).
Sub Test()
For Each Cell In Sheets(1).Range("A1:ZZ200")
If Cell.Value = "Product ID" Then
matchRow = Cell.Row
Rows(matchRow & ":" & matchRow).Select
Selection.Copy
Sheets("Sheet2").Select
ActiveSheet.Rows(matchRow).Select
ActiveSheet.Paste
Sheets("Sheet1").Select
End If
Next
End Sub
I managed to find some examples online but they copy the entire row not the individual cell.
How about this code?
I cannot use English well, but if you want, I will help you with my best.
Sub test()
For Each cell In Sheets(1).Range("A1:ZZ200")
matchrow = cell.Row
If cell.Value Like "*Product ID*" Then 'You have to use "Like" Operator if you want to use wildcard something like *,?,#...
Sheets(2).Range("B" & matchrow).Value = cell.Value
'I recommend you to use ".value" Property when deal only text, not else(like cell color, border... etc), rather than "select-copy-paste". It could be slower while hoping both sheets
ElseIf cell.Value Like "*Bolt Pattern*" Then
Sheets(2).Range("D" & matchrow).Value = cell.Value
End If
Next
End Sub
I don't think you need a macro at all. In sheet2 column B, row 2, place the following formula:
=iferror(index(SheetJS!2:2,match("*Product ID*",SheetJS!2:2,0)),"")
The iferror part just keeps the cell empty if no match is found (as opposed to giving an ugly error message). Match tells how far into row 2 the product id occurs, and index goes that far in and gets the value.
Now grab the handle at the bottom right corner of the cell, and drag it down as many rows as you have rows in the first sheet. That should bring all product IDs from Sheet JS into column B.
Similarly start in row 2 column D with
=iferror(index(SheetJS!2:2,match("*Bolt Pattern*",SheetJS!2:2,0)),"")
and drag that on down.
I'm assuming no row has more than one product id or bolt pattern, which appears to be true.
This approach does have a mild drawback, that it will leave a blank space in the sheet 2 column if the SheetJS does not have that entry in that row.
sorry for being a total noob in excel!
I have two sheets, sheet 1 named "Stocks" and sheet 2 named "Stocks search".
In "Stocks" I have from A1 to B700 values. In A column I have the stocks symbols and in B column I have the stocks' issuers symbols, so every entry in A column is unique, yet there can be repeating entries in column B.
So in sheet "Stocks search", if I enter in A1 an issuer's symbol, I want for the formula to go search in sheet "Stocks" and fetch all stocks that this issuer has in new rows.
How can this be done in a formula? Thanks in advance!
This is a VBA solution to the question. IMHO, this is more appropriate than a formula (in this case). The formula approach is OK, but there are drawbacks - you have to remember the CSE rule, and then copy the formulas down the right number of rows (which you don't know in advance), etc, etc.
This code uses the same assumptions as the formula approach.
1 - sheets = Stocks and Stock report
2 - Data in Sheets, columns A and B (header in row 1)
3 - lookup code is on Stock report
4 - Output is on Stock report
One of the advantages is that if new data is added to the Stocks sheet (i.e. the bottom row > 700), the vba automatically adjusts.
The code is self-documented. But the essence is that it creates an autofilter on "Stocks" using the lookup value as the criterion; copies the rows that meet the criteria; and pastes the result to an output range on "Stock reports". The output range is cleared before the copy/paste takes place so that there are no left-overs from any previous lookup.
I think there's something to be said for creating a dropdown list for the lookup cell. No doubt that could be automated too by getting the codes from Column A, getting the unique values, and then apply them to the lookup cell. Just a thought;)
Sub so_52537740()
' CREDITS
'
' Refer: https://stackoverflow.com/questions/17531128/copy-paste-calculate-visible-cells-from-one-column-of-a-filtered-table
' Date: 8 July 2013
' Submitted by: Jon Crowell (https://stackoverflow.com/users/138938/jon-crowell)
Dim src As Worksheet, tgt As Worksheet
Dim filterRange As Range, copyRange As Range
Dim lastRow As Long
Dim stocks As String, stockreport As String
' set values for sheet names
stocks = "Stocks"
stockreport = "Stock report"
' set values for Sheet variables
Set src = ThisWorkbook.Sheets(stocks)
Set tgt = ThisWorkbook.Sheets(stockreport)
' clear the exist target data
tgt.Range("A4:B" & Rows.Count).ClearContents
' turn off any autofilters that are already set
If src.AutoFilterMode Then src.AutoFilter.ShowAllData
' find the last row in the Stocks sheet with data in column A
lastRow = src.Range("A" & src.Rows.Count).End(xlUp).Row
' the range that we are auto-filtering (all columns)
Set filterRange = src.Range("A1:B" & lastRow)
' the range we want to copy (only columns we want to copy)
' in this case we are copying both columns A and B
' we set the range to start in row 2 to prevent copying the header
Set copyRange = src.Range("A2:B" & lastRow)
' filter range based on column A being equal the the value in Cell A1 of the stockreport
' consider making this a dropdown list so that there are no errors
filterRange.AutoFilter field:=1, Criteria1:=Format(Sheets(stockreport).Range("a1").Value)
' copy the visible cells to our target range
' note that you can easily find the last populated row on this sheet
' if you don't want to over-write your previous results
copyRange.SpecialCells(xlCellTypeVisible).copy tgt.Range("A4")
' turn off any autofilters that are already set
If src.AutoFilterMode Then src.AutoFilter.ShowAllData
End Sub
Giving due credit: There is, as they say, nothing new under the sun. I have based this answer on an excellent piece of work by Jon Crowell on a question in StackOverflow "Copy/Paste/Calculate Visible Cells from One Column of a Filtered Table" in July 2013. Just goes to show what a bit of Googling and perseverance can achieve.
I believe I have an answer for you.
Try
=IFERROR(INDEX('Stocks Search'!$A$1:$A$700,SMALL(IF('Stocks Search'!$B$1:$B$700=$A$1,ROW('Stocks Search'!$A$1:$A$700)-MIN(ROW('Stocks Search'!$A$1:$A$700))+1),COLUMNS($A$1:A1))),"")
This is a CSE formula. What that means is once you enter it into cell B1, you will need to press Control+Shift+Enter. Once you do this, these brackets will appear around your formula {}
Click the fill button in the bottom right of the cell and drag the formula to the right (you will need to do this for as many cells as it is possible for answers). So if Company A has 40 possible answers, you will need to have this formula go at least 40 cells to the right.
The application of CSE formulas can be tricky. Essentially you need to go to the end of the formula in the formula bar, and then use Control+Shift+Enter.
I hope this helps.
I have two excel sheets both with matching product numbers. What I need to do is match the product numbers and then copy a column from the first sheet to the second.
My example:
Column C in the first sheet contains product numbers
Column A in the second sheet contains product numbers
I want to match C & A and then copy column B from the first to the second sheet.
Sorry if this has been answered before, my knowledge is basic but I am trying to learn
Thanks for any help.
CD
Assuming your numbers to match start in C2 (headers in row 1) and numbers to copy in AC2 on Sheet1, this should do what you want. Paste it into AC2 on Sheet2 and then drag copy to the length of column A on Sheet2.
=IF(IFNA(MATCH(A2,Sheet1!C:C,0), FALSE), INDIRECT("Sheet1!AC"&MATCH(A2, Sheet1!C:C, 0)), "Not Found")
Note this will give "Not Found" for a value on Sheet2 which is not found on Sheet1, you can change that by just replacing the string "Not Found" in the formula with whatever you want (e.g. 0).
Formula:
You can use OFFSET with IF. In B1 of sheet 2 for example you could put, drag down for as many rows as required,
=IF(A1=Sheet1!C1,OFFSET(Sheet1!A1,0,COLUMNS(Sheet1!A:AC)-1,1,1))
If you set your data up as a table in sheet 2 (Ctrl + T with an populated cell selected) then add this formula to the appropriate column it will autofilter down the formula.
Or:
With code in a standard module:
Public Sub AddFormula()
Dim rng As Range
With Worksheets("Sheet2")
If Application.WorksheetFunction.Subtotal(103, .Columns(1).Cells) > 0 Then
For Each rng In Intersect(.Columns(1), .UsedRange)
If Not IsEmpty(rng) And Not IsError(rng) Then 'assume ignore empty cells
If rng = Worksheets("Sheet1").Cells(rng.Row, "C") Then Worksheets("Sheet1").Cells(rng.Row, "AC").Copy rng.Offset(, 1) 'determine where you want value to go
End If
Next rng
End If
End With
End Sub
Note:
This is based on your comment that you are comparing sheet2 col A with sheet1 col C and copying sheet1 col AC if match.
I assume that the product numbers in both sheets are unique. If that, I suggest use the offset and match formulas to achieve what you want.
sorry for my half-baked answer due to i just typed them with phone and it is not convenient to input complicated style, here is the additional information:
the match formula is used to query the location of the target product number in the original sheet( sheet 1 in your case above);
after we located the position of the target product number, extract the information you wanted through the offset formula.
here are the specific process:
Sheet 1 represent the original information and sheet 2 represent the target one. What we required to do is copy the info in col D of sheet 1 to col D of sheet through the product:
OFFSET($D$5,MATCH(I6,$D$5:$D$16,0)-1,1,1,1)
OFFSET($D$5,MATCH(I7,$D$5:$D$16,0)-1,1,1,1)
OFFSET($D$5,MATCH(I8,$D$5:$D$16,0)-1,1,1,1)
OFFSET($D$5,MATCH(I9,$D$5:$D$16,0)-1,1,1,1)
OFFSET($D$5,MATCH(I10,$D$5:$D$16,0)-1,1,1,1)
or you can refer to the output directly:
enter image description here
for more information about these two formulas, you can refer to the help of excel of google.