Macro excel: Paste values and update 2 cells - vba

I apologize for being newbie as I am having difficulty with this concept. I really don't know where to start.
I just need a code in Sheet2 using an 'Update Button' to do the following:
In sheet1, this information will come from different Team Leaders as duplicate or even triplicate records shown in example 'Seat no. 1.2' can occur.
In sheet2, under 'Seat No.', this is constant and will never change (serves as my reference for my other Pivot and lookup codes)
In sheet2 columns, under 'User 1', the code will paste the 1st value detected; Under 'User2', the code will paste the 2nd value detected; Under unassign, the code will paste the 3rd value detected
In sheet2 column under Status, it will show Solo if only 1user, 'Sharing' if there are 2 users and 'Vacant' if no user.
Note: only two users are allowed for every Seat No.
Hope you can help me. Thank you so much

You don't need to use macro for this. In user 1 column use this:
=IF(ISERROR(VLOOKUP(Sheet2!A2,Sheet1!$A$2:$B$50,2,0)),"",VLOOKUP(Sheet2!A2,Sheet1!$A$2:$B$50,2,0)),
where 50 replace with number of your rows.
In user 2 use this:
=IF(SUMIF(Sheet1!$A$2:$A$50,Sheet2!A2)>1,IF(ISERROR(VLOOKUP(Sheet2!A2,OFFSET(Sheet1!$A$2,MATCH(Sheet2!A2,Sheet1!$A$2:$A$50,0),0,50-MATCH(Sheet2!A2,Sheet1!$A$2:$A$50,0),2),2,0)),"",VLOOKUP(Sheet2!A2,OFFSET(Sheet1!$A$2,MATCH(Sheet2!A2,Sheet1!$A$2:$A$50,0),0,7-MATCH(Sheet2!A2,Sheet1!$A$2:$A$50,0),2),2,0)),"")
and again replace 50 with number of your rows.
In status column, use IF with SUMIF.
And in Unassign column, use vlookup like in first column, but from down to up. There is lot of articles about it. Dont forget to use if in start, which will check if there is 3 IDs for seat.

This doesn't need VBA unless you insist to do so:
User1 column:
=IFERROR(IF(VLOOKUP(A2,Sheet1!$A$2:$B$9,2,0)=0,"",VLOOKUP(A2,Sheet1!$A$2:$B$9,2,0)),"")
User2 column (array formula, press Ctrl + Shift + Enter keys simultaneously):
=IFERROR(INDEX(Sheet1!$B$2:$B$9,SMALL(IF($A2=Sheet1!$A$2:$A$9,ROW(Sheet1!$A$2:$A$9)-ROW($A$2)+1),2)),"")
Status column:
=IF(COUNT(B2:C2)=0,"Vacant",IF(COUNT(B2:C2)=1,"Solo","Sharing"))
Unassign column (array formula, press Ctrl + Shift + Enter keys simultaneously):
=IFERROR(INDEX(Sheet1!$B$2:$B$9,SMALL(IF($A2=Sheet1!$A$2:$A$9,ROW(Sheet1!$A$2:$A$9)-ROW($A$2)+1),3)),"")
Hope this helps.

Related

Find number of rows in an already filtered Column A in Excel

I have got an Excel spreadsheet. This spreadsheet has just one tab in it. The Tab name is dynamic in nature and changes every week also the number of rows.
I have column A filtered already with a VBA macro. A1 has the header.
Now, I wanna find how many rows are there in this already filtered column A.
I am looking for any VBA function.
I have tried using Subtotal function.
=Subtotal(103,A2:A1345)
But I don't know the end range. As of now the end range is A1345. It will change every time in future if the new rows are added.
I tried multiple things but those did not work. I am quite new to VBA.
If A1 will never be blank, you could use (in a column other than A)
=Subtotal(103,A:A)-1.
Or, if there will be data below your table not to be counted, then format your table as a Table and use structured references (and this formula could go into column A)
=SUBTOTAL(103,Table1[column_header])
You can put the formula in column A if you use another column's last populated cell as the demarcation point.
If column B contains numbers then,
=subtotal(103, a2:index(a:a, match(1e99, b:b)))
If column B contains text then,
=subtotal(103, a2:index(a:a, match("zzz", b:b)))

Removing Duplicates in Excel with or without VBA

Chart Example
Hello All,
I am looking for some help in cleaning up an organizational chart that I have in excel. Right now, there are many duplicates as the linked picture shows. I need to remove all the duplicates, and shift the unique values over into the blank spaces
(i.e., Bill G, Bill G, Fred K, Fred K, Joe X ---> Bill G, Fred K, Joe X).
I have been trying to get it done using Excel Formulas (=IF(A1=B1, B1, A1)), but it does not repeat correctly across the Sheet, especially because the different rows have varying numbers of occupied columns.
I'd appreciate any help that I can get. Thank you!
No need for VBA. Use Data, Advanced filter, choose Copy to another location and check Unique records only
Select your range
Go to the Data tab
In the Data Tools pane, select "Remove Duplicates"
first a formula to bring unique only. the formula display duplicates as 0.
then while still selecting the formula range, open the "go to special" dialog box
select Formulas > Numbers
all formula output zeros will be selected
press `Ctrl + minus(-) to delete cells, select "shift cells left"
end result

Dynamic reference in excel formula

I have the following array formula which works for what I want to do but I'm trying to change the formula when a user selects a value.
=INDEX($A$2:$B$70,SMALL(IF($A$2:$B$70=$A$121,ROW($A$2:$B$70)),ROW(1:1))-1,1)
It's used for a monthly report and the user will choose from a drop down the day of the month, e.g 1,2,3 - 31.
So if the user selects 1 from the drop down menu I want the formula to use the above formula.
If they select 2 for example I want the formula to move over a column so it would change to
=INDEX($A$2:$C$70,SMALL(IF($A$2:$C$70=$A$121,ROW($A$2:$C$70)),ROW(1:1))-1,1)
and so on moving over a column at a time.
It this possible at all or can it even be done without VBA?
I have an example of what I want done on the following link
https://docs.google.com/spreadsheets/d/1MDOzoQxYLgW-UOyljZsMwSu8zyAB7O2k1V-bTNP5_F0/edit?usp=sharing
All the data is on the first tab called staff. Each employee has a row and the duty assigned under the corresponding day column.
On the Roster tab it summarises each day. So what I am trying to get to happen is when you choose the day of the month (or preferably the actual date) the sheet changes to reflect the data.
At the moment the code I have working does for just Day 1 because the column references are coded into the formula. I was hoping to somehow choose 6 for example from the drop down and then the formula will map chosen day to the corresponding range in the raw data and update the formula and change the formula from Staff!$A$2:$B$68 to Staff!$A$2:$G$68.
If the formula finds no more entries if shows #NUM! but I intended to use the function ISERROR() to replace #NUM! with "".
This is what I'm trying to achieve it if makes sense?
There are a few issues here/ You are returning the value from column A so the first range can be $A$2:$A$70 and that means you don't need the 1 to specify the column_num. The IF statement was covering A2:C70 when you really only want either B2:70 or C2:C70 depending on the 1 or 2.
Assuming that A122 has either a 1 or 2 in it then,
=INDEX($A$2:$A$70, SMALL(IF(INDEX($B$2:$C$70, 0, $A$122) = $A$121, ROW($1:$69)), ROW(1:1)))
Standard non-array alternative,
=INDEX($A$2:$A$70, SMALL(INDEX(ROW($1:$69)+(INDEX($B$2:$C$70, 0, $A$122) <> $A$121)*1E+99,, ), ROW(1:1)))

Excel Lookup Data Based on Column Name not Cell Name

I am trying to accomplish a strange task in excel and don't know how to go about it. I'm using Excel 2007 at work and I know very basic vba.
I want to automate a process where a person takes three spreadsheets and dumps certain data from them into one master sheet. The three spreadsheets vary every month in their column order, so unfortunately I can't just program vlookups to run and get the data.
I could be wrong, but it seems like Vlookup Match, Index Match Match, etc. wouldn't work either because they are still referencing cells. I basically need something that will find a column based on the text in the column, rather than its location, because the location will change, but the text will always be the same.
I have two ideas but I have no idea if they work and don't really know where to start on implementing them:
Convert the three spreadsheets to tables and reference the headings with table syntax (I haven't been able to get this to work)
Complex VBA that IDs everything
Can anyone help point me in the right direction to accomplish this task? Thanks so much for your help.
EDIT EXAMPLE
My main template that I'm trying to dump things into is just going to have the ID#s and empty columns:
ID# AltID# Deal
1
2
3
4
5
And then another spread sheet might have look like this
ID# AltID# Deal
1 10101 AAAA
2 20202 BBBB
3 30303 CCCC
4 40404 DDDD
5 50505 EEEE
I could of course vlookup, but the problem is next month, those columns in the second spreadsheet won't be in the same place, in the same order. They could be all the way on colum DD or whatever. So I need a formula that looks them up regardless of the columns location. Just matching them by the heading text. I hope that clarifies...
If you combine VLOOKUP with MATCH you can search based on column name, not index. Remember that the MATCH function returns the numeric index of the match. Let's assume that your data looks like the below:
NAME DAY1 DAY2 DAY3
Bob 123 345 567
Tim 456 789 998
A functioning Vlookup to return the DAY2 column for Tim would look like:
=VLOOKUP("Tim", A2:D3,MATCH("DAY2",A1:D1,0),FALSE)
A couple of notes. Where I've hard coded in words, you can use cell references.
Here is one idea:
get the index of the column ID# in Sheet2 MATCH("ID#",Sheet2!$1:$1,0)
convert to a character: CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64)
get the column range:
INDIRECT(
CONCATENATE("Sheet2!",
CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64),":",
CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64)))
similarly for column AltID#:
INDIRECT(
CONCATENATE("Sheet2!",
CHAR(MATCH("AltID#",Sheet2!$1:$1,0)+64),":",
CHAR(MATCH("AltID#",Sheet2!$1:$1,0)+64)))
with range of ID# and AltID#, we can do the match+index:
=INDEX(
INDIRECT(
CONCATENATE("Sheet2!",
CHAR(MATCH("AltID#",Sheet2!$1:$1,0)+64),":",
CHAR(MATCH("AltID#",Sheet2!$1:$1,0)+64))),
MATCH(A2,INDIRECT(
CONCATENATE("Sheet2!",
CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64),":",
CHAR(MATCH("ID#",Sheet2!$1:$1,0)+64))),0))
Here is an idea to consider:
Give a name to cell ID# e.g "dataJanuary" and use this named-cell as reference using an OFFSET function then you can explore it with vlookup or index-match function or other method.
Next month even if the ID# column is moved to other column or row, it will always reference to the same data since the cell is already named with "dataJanuary".

Replace or recode several different values by a single value in an Excel file

I have an Excel worksheet which contains data in several columns. For a specific column, I will need Excel to replace all values between, say 10 to 15, by the value 1 and values between 16 and 20 by the value 2 and so forth.
I know how to do it for a single value; ie: I can replace value 10 by 1, 11 by 1 and so on. But this will be a tedious exercise. Are there some lines of codes that can execute this task?
Thanks for your help.
regards,
Ali
If you do not need to automate this with a macro or repeat often, you can do this quickly right on the spreadsheet.
Insert a new column to the right of the column to change. Let's say the column was A and you just created a new column B.
Enter the formula =INT(A1/5) - 1 in cell B1.
Copy this formula to all cells in column B for the extent of the cells in column A.
Copy the cells in column B and paste to column A using right-click, "Paste special...", Values, then click Ok.
Delete column B (this is a temporary/work column).
This will replace the values in column A with the adjusted values in column B. Proceed with any other columns.
Here's a quick and dirty way, that will have to be modified based on what values you really want to change to and from. This converts 11 to 15 to 1, and 16 to 20 to 2, etc.
You'll probably want to put a button on the spreadsheet, and then right click and choose "View Code". Then enter the following between the Sub and End Sub statement. "RangetoChange" is the name of a named range, OR you can put in the range itself, like "A1:A100". Once it's all entered, then you just get out of design mode (that you entered to place the button), then click the button. Make sure that you change the formula to what you really want the result to be.
Dim A() As Variant
Dim i As Integer
A = Range("RangetoChange")
For i = 1 To (UBound(A) - LBound(A) + 1)
A(i, 1) = (A(i, 1) \ 5) - 1
Next i
Range("RangetoChange") = A