Is For loop the best way to check if Cell IsNumeric? - excel

I have to do a VBA code that check if the Cells in Column "A" IsNumber. I work with sheets that have 2k ~ 3k rows per table.
I wanna know if a For loop thru the cells in the range, is the best Optimal way to do this.
Dim tmpCell as Range
For each tmpCell in Range("A1:B5").Columns(1)
If IsNumeric(tmpCell) = True Then
tmpCell = tmpCell.Value*1
End if
next tmpCell
I need to verify if the cell is Number, because when I paste the info from a Pivot Table, one column is copied as string, not number.
Thank you, for your time.
Edit:
My table is something like this.
The numbers in the "A" Column is in string, not number.
| A1 | B1 | C1 |
1| 1234 | 1 | 2 |
2| 5678 | 2 | 4 |
3| 9012 | 3 | 5 |
4|Total | 5 | 11 |

Related

Excel Macro to find a cell based on matching two values (Row/Column) and replace value in cell

I am having some trouble trying to find a solution to an issue I have. I have two excel sheets that I would like to find or index values from one sheet to the other and then replace the value of the cell after locating the cell.
I think maybe a better way to picture is that I have a excel sheet "Data1" that consists of three columns with rows of data.
Example of Sheet 1:
A B c
1 | Header 1 | Header 2 | Header 3 |
2 | -------- | -------------- |----------|
3 | 123456 | AABB |12AB12AB |
4 | 678910 | BBCC |34CD34CD |
I have a second Excel Sheet "Data2" that consists of multiple columns and rows of data.
Example Sheet "Data2":
A B C D E
1 | Header1 | BBCC | CCDD | AABB | EEFF |
2 | -------- | -----------|----------|---------|---------|
3 | 123456 | ValueX | ValueY | ValueZ | ValueB |
4 | 678910 | ValueXX | ValueXY | ValueYY | ValueZZ |
What I would like to do is run a macro:
To first, match the value A3 (123456) in Sheet "Data1" to the same value in Column A from Sheet "Data2"
Second, match the value B3 (AABB) in Sheet "Data1" to the same value in Row 1 from Sheet "Data2"
Third, replace the value in the corresponding cell with the value from Sheet "Data1" cell C3.
Then, Loop and replace all cells until the rows of data from Sheet "Data1" end.
The Values in Sheet "Data2" should then change to look like:
A B C D E
1 | Header1 | BBCC | CCDD | AABB | EEFF |
2 | -------- | -----------|----------|----------|---------|
3 | 123456 | ValueX | ValueY | 12AB12AB | ValueB |
4 | 678910 | 34CD34CD | ValueXY | ValueYY | ValueZZ |
Please let me know what you think and I hope I laid out the requirements as simple as possible. Thank you for your time and support to help me work this solution. Cheers
IF your version of Excel supports XLOOKUP then you can set up Sheet "Data3" with the same column and row headers and use this functions for the data cells.
=XLOOKUP($A3&B$1,Data1!$A$3:$A$4&Data1!$B$3:$B$4,Data1!$C$3:$C$4,Data2!B3)
It takes the data in data2 and overwrites it with the data from data1 if there is a match.
More on XLOOKUP

Excel formul to count Table Range using month from date text

I have an excel workbook where I am trying to count the number of apples in a named table. The workbook has multle sheets each named Jan, Feb, Mar, etc. with a corresponding table range of the same name.
My main worksheet has a list of months as columns and fruit as rows, I want to use a countif or suitable function to count the number of each fruit per month using the column heading as the worksheet portion of the formula.
This is what I have tried, this works, but has to be manually coded for each month, i would prefer it be more dynamic.
=COUNTIF(JAN[Labels],$A2)
Note: A2 contains the word apple
I have tried to get the month from the column date but it doesnt work
=COUNTIF(TEXT(E25,"mmm")[Labels],$A2)
This is roughly what the "master" table should look like (for clarity)
| | Jan-20 | Feb-20 | Mar-20 | .... |
| Apple | 4 | 3 | 5 | ... |
| Pear | 5 | 4 | 9 | ... |
EDIT:
Just to assist with anyone trying to help, this is roughly what a table on another sheet will look like:
| invoice | labels|
| 12535 | Apple |
| 12536 | Pear |
| 12537 | Apple |
This table would be a named table of Jan or Feb, etc.
Please try this:-
=COUNTIF(INDIRECT(TEXT(G2,"mmm")),"A")
G2 contains a proper date.
Here is a variation of the above where column 2 of the table is specified as the range to count in.
=COUNTIF(INDEX(INDIRECT(TEXT(G2,"mmm")),0,2),"B")
If you must use column captions to identify the column I would suggest MATCH to find it.
OK, so I found an answer, combining the above answer by Variatus with an additional new row.
| A | B | C | D |
1| | Jan-20 | Feb-20 | Mar-20 |
2| |JAN[Labels]|FEB[Labels]|MAR[Labels]| <- =UPPER(TEXT(B1,"MMM"))&"[Labels]"
3|Apple | 5 | 7 | 3 | <- =COUNTIF(INDIRECT(B$2),$A3)
4|Pear | 7 | 2 | 9 |
5|Orange| 1 | 3 | 3 |
So formula in B2 makes an uppercase text value of the month from B1 plus the column name Labels.
The formula in B3 (and down) counts the number of instances of the fruit from the named table & column shown in B2.

Excel - Transpose data from multiple rows to single column with matched value

Ok, so I have some data that I want to convert from multiple rows to multiple columns.
My input data looks loosely like this -
+----------+----------------+-----------------+
| SKU | Attribute Name | Attribute Value |
+----------+----------------+-----------------+
| Product1 | Colour | Black |
| Product1 | Size | Large |
| Product1 | Height | 20cm |
| Product1 | Width | 40cm |
| Product2 | Colour | Red |
| Product2 | Width | 30cm |
| Product2 | Size | Large |
| Product3 | Height | 25cm |
| Product3 | Width | 30cm |
| Product3 | Length | 90cm |
| Product3 | Weight | 5kg |
| Product3 | Size | Large |
| Product3 | Colour | Blue |
+----------+----------------+-----------------+
What I want to achieve is an output like this -
+----------+--------+--------+--------+-------+--------+-------+
| SKU | Colour | Height | Length | Size | Weight | Width |
+----------+--------+--------+--------+-------+--------+-------+
| Product1 | Black | 20cm | | Large | | 40cm |
| Product2 | Red | | | Large | | 30cm |
| Product3 | Blue | 25cm | 90cm | Large | 5kg | 30cm |
+----------+--------+--------+--------+-------+--------+-------+
I've tried Pivot tables, but you can only return numeric values, rather than the text values I'm looking for.
I know I could probably achieve it using a number of step looking up values and filling them, but I feel like there should be a more simplistic way to achieve this. Maybe it's something better achieved in database rather than a spreadsheet.
Any help would be very much appreciated.
You can do this in ̶5̶ ̶s̶t̶e̶p̶s̶ 4 steps with Powerquery. This is in-built for 2016 and a free add-in from Microsoft from 2013 on wards ( or 2010 Professional Plus with Software Assurance). See info https://www.microsoft.com/en-gb/download/details.aspx?id=39379
The advantage is you can easily add rows to the source and simply refresh the query.
1) You select any cell in the range, then in 2016 Get & Transform tab, earlier version use the Powerquery tab, select data from table. A window will pop up with your range of data in:
2) Transform > Pivot column > Attribute Name column for Attribute Value in Values Column (used advanced options to select "Don't aggregate")
3) Drag columns around to desired arrangement
4) Home > Close and load to sheet
Here is a version without the column re-ordering
Edit:
Thanks to #Ron Rosenfeld for reminding me that truly null values don't need replacing with blanks as they will appear as blanks when written to the sheet.
So this step was removed:
4) Highlight columns to replace nulls in and go to transform > replace values > and
Value to Find: null
Replace With:
You could do this using a helper column and then match it using index + match. Not as simple as you thought, but does work.
1) Add helper column to your data (call it 'Helper'). =concat(SKU,'Attribute Name')
2) Use a pivot to get a unique list of SKUs in the rows so that it's easy to update once the data changes. (I'm assuming this is in column A and values start at row 4).
3) Use another pivot to get a unique list of Attributes in the columns next to the other pivot. Then you have the structure of your results. (I'm assuming the first value is in B3).
4) Index match the values of the table =index('Attribute Value', match(concat($A4,B$3),'Helper',0))
Note though that this only works when each combination of SKU and Attribute is unique.
This assumes that the data is in columns A through C:
Sub croupier()
Dim i As Long, N As Long, vA As String, vB As String, vC As String
Dim rw As Long, cl As Long
' setup column headers
Columns(2).SpecialCells(2).Offset(1).Copy Range("D1")
Columns(4).RemoveDuplicates Columns:=1, Header:=xlNo
Columns(4).SpecialCells(2).Copy
Range("E1").PasteSpecial Transpose:=True
Columns(4).SpecialCells(2).Clear
' setup row headers
Columns(1).SpecialCells(2).Copy Range("D1")
Columns(4).RemoveDuplicates Columns:=1, Header:=xlYes
' deal the data
N = Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To N
vA = Cells(i, 1)
vB = Cells(i, 2)
vC = Cells(i, 3)
cl = Rows(1).Find(what:=vB, after:=Range("A1")).Column
rw = Columns(4).Find(what:=vA, after:=Range("D1")).Row
Cells(rw, cl) = vC
Next i
End Sub

Row Numbers in Excel Table

I have the following basic table:
1|
2| Title....
3|
4|
5| | Row Index | Type | Etc... |
6| | 1 | abc | ..... |
7| | 2 | def | ..... |
8| | 3 | ghi | ..... |
9| | 4 | jkl | ..... |
Note that the table does not start on Excel row 1. Technically ROW()-5 would work, but I do not want to hardcode the actual row the table starts on.
My formula for Row Index is:
=ROW()-CELL("row")+1
This works fine, except for when you edit another cell in the table. It seems that the formula assumes the row you edit is index 0 and starts the row count from there.
For instance, if I were to edit a cell in row 3 in the above table, the Row Index values would look like this:
| Row Index | Type | Etc... |
| -1 | abc | ..... |
| 0 | def | ..... |
| 1 | ghi | ..... |
| 2 | jkl | ..... |
After each edit, I think have to re-edit a cell in the top row to get the Row Index values correct again.
Is there a reliable way to display row numbers in a table?
If it is an actual Excel Table (Insert tab > Table or Home tab > Format as Table):
=ROW()-ROW([#Headers])
or
=ROW()-ROW(Table1)+1
Otherwise, you can use the absolute address:
=ROW()-ROW($5:$5)
Remove the CELL("row") and just use the formula
=ROW() - 5
The ROW function returns the row number of the cell containing the formula, which is what you want.
The CELL function, on the other hand, returns information about the last changed cell, which is why you see the strange behavior.
CELL(info_type, [reference])
Reference   Optional. The cell that you want information about. If omitted, the information specified in the Info_type argument is returned for the last cell that was changed. ...
Even if CELL returns information about the current cell, what you would get from ROW() - CELL("Row", <current_cell>) + 1 would be the constant 1 because the two functions cancel each other.

excel return the value of a cell based on two other values

What I'm trying to do is a little complex but I think it's doable in Excel.
I have two worksheets in a workbook on sheet one I have this...
| Code1 | Code2 | Code3 | Code4 |
| BA1 | xxxxx | xxxxx | |
| BA2 | xxxxx | xxxxx | |
| BA3 | xxxxx | xxxxx | |
And on the second sheet...
| CodeA | CodeB | CodeC | CodeD |
| BA1 | 1 | date | text |
| BA3 | 1 | date | text |
| BA1 | 2 | date | text |
| BA2 | 1 | date | text |
| BA1 | 3 | date | text |
| BA3 | 2 | date | text |
| BA2 | 2 | date | text |
What I want to do is lookup Code1 on sheet one and find it in the second sheet in CodeA then find the highest CodeB for CodeA and then concatenate CodeC and CodeD and place them on Sheet one in Code4.
I hope that makes sense, Thanks for any advice.
I think I understand. Does this look correct?
Sorry for the swedish formulas but it's an array formula that you add with CTRL+SHIFT+ENTER.
The formula in english is:
{=MAX(IF(Data=A2,CodeB;-1))}
And the named range Data is Column H and I, and CodeB is Column I.
If it does not find the value it returns -1
Sorry noticed now that I only did half of the job.
Make another named range called Table that spans column I to K (Code B -> Code D).
And in column code3 add this formula:
=Vlookup(B2,Table,2,false)
And in code4:
=Vlookup(B2,Table,3,false)
And you should get:
This should find the results you are looking for.
This is an array formula so you will need to press CTRL+SHIFT+ENTER once you have entered it into the formula bar, this will have to done for every formula you add to the column.
As it is an array formula I have only written it to reference rows 1 to 18, you will need to update all references to include you last row.
Columns titled CODE1(to 4) are on the first sheet (Sheet 1)
Columns titled CODEA(to D) are on the Second sheet (Sheet 2)
=CONCATENATE(VLOOKUP(CONCATENATE(A2,MAX(IF(Sheet2!A:A=A2,Sheet2!B:B,-1))), CHOOSE({1,2},Sheet2!A1:A18 & Sheet2!B1:B18, Sheet2!C1:C18 ),2,0)," ",VLOOKUP(CONCATENATE(A2,MAX(IF(Sheet2!A:A=A2,Sheet2!B:B,-1))), CHOOSE({1,2},Sheet2!A1:A18 & Sheet2!B1:B18, Sheet2!D1:D18 ),2,0))
If you do not require a space between the dates, just remove " ", from the middle of the formula.

Resources