Excel VBA Code to transpose multiple columns into multiple rows - vba

Can somebody please help, i'm a newbie in VBA, i would like to thank you in advance for your help. If there are any links where my question has already been adressed please point me in the right direction. I have searched here and on other sites but i couldn't find anything that atleast get me started. I would like to create VBA code that loops through cells in every row and transpose them into seperate rows as illustrated below.
I have an excel spreadsheet with 12000 rows of data and multiple columns. For each row i have columns "A" to "Q" as static fields. Name, DOB, ID_Number, e.t.c. From columns "Q" to "DD", i have repeated data on "City" and "RegDate" columns, for example: City1, RegDate1, City2, RegDate2, City3, RegDate3,..& CityN, RegDateN. The City names are used as Headers and the data cells show "R" under every city where a person is registered and the registration date in the column next to it, otherwise there is no entry.
I would like to transform this data so that for every City where a person is registered, i will have a new row of data showing the static fields "A" to "P", "City", and "RegDate" i.e. after column "P" i will only have two columns "City" and "RegDate".
I'm really struggling with creating code that loops from Column Q to Column DD creating a new row when ever an "R" is encountered copying rows Columns "A" to "P" and inserting the Name of the City in the new column "Q" and the RegDate in the new Column "R", before moving on to the next row until all the 12000 rows have been transformed.
Any help to get me started would be greatly appreciated especially on setting up the looping that creates a new role for every record with an "R" encountered.

Have you considered just putting this information in two new columns to the far right (DE and DF)? Then you could either hide Q to DD, or delete those columns.
As for the looping code to do this:
Dim cr As Long 'current row
Dim cc As Long 'current column
For cr = 2 To 12000
For cc = 17 To 108 Step 2
If Cells(cr, cc).Value = "R" Then
'make column 109 (DE) in current row = city name
Cells(cr, 109).Value = Cells(1, cc).Value
'make column 110 (DF) in current row = date of registration
Cells(cr, 110).Value = Cells(cr, cc + 1).Value
End If
Next
Next

Related

Deleting all columns between the first one and the last four on a sheet

I have a worksheet here with multiple columns full of data, ranging from cell AA to CT currently. The first column contains rows with headings and is frozen. Data is added to the end column of this range weekly. & Then all columns between the first and the last four are deleted (to show a month's worth of data but keep the headings intact).
I'm very new to VBA and I've been trying to write some code to automate this, so far I've managed to select the 5th column in from the end. But I can't get it to select the columns in between the 4th column from the end and Cell AA:
Sub DeleteColumns()
Dim i
i = Range("KFIData").End(xlToRight).Offset(0,-4).EntireColumn.Select
Columns("AA:ColumnFive").Delete
End Sub
Am I going about this completely the wrong way?
Many thanks
Well if you managed to catch column 5 from the end, use this statement:
Range(Columns("AA"), Columns(ColumnFiveFromEnd)).Delete
ColumnFiveFromEnd can be a number as well as a text identifier.

Hiding Columns by matching a cell entry to the respective row data of the columns

I am trying to filter out columns which do not contain the letter I enter in a cell which corresponds to the row.
I have constructed a matrix of Blanks, K's and E's
On the top there is names
on the left there are categories
for each name and category there is an assigned K, E or Blank
I want to enter either K or E next to each category (ideally using a drop down menu) and that will filter out every name which does not have the letter I entered in respect to this particular category.
One person may have a K, E or Blank but not a combination of them within a particular catagory.
I have searched everywhere for how to do this but I'm stumped. I'm not particularly proficient in VBA or Excel but I feel like this should be a simple problem which is why it's frustrating
I'm tryin to create something like this:
If
the value in cell(x,n) [column, row] = "K" or "E" Then for the
range to right of column x
hide every column which does not contain an "E" or "K" in row n
or you could say only show columns which contain an E or K in row n
Thanks in advance for any help!

Excel VBA find in Table

Im having a list of event participants in an Excel Sheet (Col A: Lastname; Col B: Firstname) and a Membership Table with the same plus info colums like birthdate and sex.
No I want to loop through the event list and do some actions on the birthday/sex of the participants. I can express that in MySQL
SELECT birthdate, sex FROM members WHERE lastname = LASTNAME AND firstname = FIRSTNAME
Where LASTNAME & FIRSTNAME are pulled from the participants table. I can figure out how to create a Loop through the event table but I got trouble on how to pull the data from the Membership Table.
Im just not used to Excel VBA so any help to start me off would be greatly appreciated
So far I got following Loop:
Dim participantCount As Integer
Dim sh As Worksheet
Dim rw As Range
Set sh = Sheets(INP_tblakt.Value)
For Each rw In sh.Rows
If sh.Cells(rw.Row, 1).Value = "" And sh.Cells(rw.Row, 2).Value = "" Then
Exit For
End If
participantCount = participantCount + 1
Next rw
EDIT: To Clearify
I got the loop above in wich I want to insert a "function" wich looks up in another sheet the row where A? = sh.Cells(rw.Row,1) and B? = sh.Cells(rw.Row,2) So that I then can get the value from D? and E? to use it for further calculation.
The VBA function Find does only support the matching of one Colum. I now found MATCH and IDEX but couldnt succesfully implement them.
(Hopefully this does help to understand the question, Thanks in advance for help)
Assuming the members table is an Excel Table, you can combine MATCH and OFFSET to get what you need. There may be a faster way but this is what I got.
Consider below table (on same sheet for screenshot):
C3 is the cell with formula that finds the DOB for matching FirstName A3 and LastName B3 from the members table.
The formula is:
=IF(MATCH(A3,members[FirstName],0)=MATCH(B3,members[LastName],0),
OFFSET(members[[#Headers],[DOB]],MATCH(A3,members[FirstName],0),0),
"No Match")
Since we need to exact match 2 fields (FirstName and LastName), we need the Matches to be on the same position. Hence the condition is:MATCH(A3,members[FirstName],0)=MATCH(B3,members[LastName],0)
Once an exact match is found, we can use OFFSET to locate the n'th row from the field we want to extract:OFFSET(members[[#Headers],[DOB]],MATCH(A3,members[FirstName],0),0) It means get the value from matched row of table members with header "DOB". Change the text DOB to the desired header name of your lookup table.
Otherwise "No Match" is returned.

How do I compare two columns in different sheets for non existing values and then copy them to the main sheet?

Firstly, I am no expert with VBA, just searching for similar situation copying them, changing the code a bit and hoping for the best.
So I need to make a macro that compares two sheets. One of the sheets is the one that contains history information and all the specific names in Column A, where in the other sheet I paste daily information, where the specific names is always in column C and starts with row 7. The existing names could disappear or new names could be added and there will be duplicates.
What I need is for the code to first compare these two Columns for new names, if such are found copy them and past them in the history sheets A columns 2nd row, the existing names get moved down, so that they don't get deleted.
In short words saying If duplicate do nothing, else copy to history sheet.
Thank you in advance for all the help
Not sure of what your logic would be, but here are some VBA Pointers:
To compare columns in different sheets:
If Sheets("Sheet1").Range("ColRow").Value <> Sheets("Sheet2").Range("Col2Row2").Value Then...
Or you could replace the sheet names with (1) and (2) [or whatever order they are in the workbook].
For instance:
If Sheets(1).Range("A2").Value <> Sheets(2).Range("C7").Value Then ...
Assignment to a cell works similarly. You can use a variable as an index:
Dim i1 as integer
Dim i2 as integer
i2 = 7
For i1 = 1 to 50
If Sheets(1).Range("A" + CStr(i1)).Value <> Sheets(2).Range("C" + CStr(i2)).Value Then
Sheets(1).Range("B" + Cstr(i1)).Value = Sheets(2).Range("C" + CStr(i2)).Value
End If
i2 = i2 + 1
Next i1

vlookup if name is matched display employee id

Ive never used vlookups i have a spreedsheet not sure if this is the right function. I have two sheets
Sheet 1
first name last name username
Sheet 2
first name last name employee id business unit
I need in column D on sheet 1 to have employee id ive below. Pay no attention to column letters and sheets because i moved to another sheet to try getting this right.
=MATCH(B11,Sheet1!C:C,0)
Any help is much appreciated.
So you realize you have to match both first and last names? There are several ways to accomplish this depending on how many employees you have in sheet 2: a) small list could a two-column search using array formula; b) large list just create another column in both sheets joining last & first names and do a MATCH or VLOOKUP on them.
Since your needs are simple and to illustrate option (b):
Insert a column in both Sheet1 and Sheet2 after the "last name"; you should now have an empty column C in both sheets.
Assuming you have column headers in row one, and thus data starts in row two, set cell C2 in both sheets with function =B2&","&A2, then fill-down that formula on both sheets in all rows.
Set Sheet1 cell E2 to formula =VLOOKUP(Sheet1!C2, Sheet2!$C:$D, 2, False), and fill-down that formula in all rows.
Voila, employee IDs on Sheet1. I do have to say this is so Excel 101. There are all sorts of examples and tutorials on this easily found using even the most trivial Google searches.