User defined concatenate - excel

I am trying to expand my annual planning document to give me more information. Currently however I am stuck.
My current Sheet is laid out as follows:
I need to create a second sheet that concatenates the client name with each column heading there is a "yes" value in, as its own separate line.
Example 1 in the new sheet would become:
Example 1 - Annuals
Example 1 - Xero Fee
I had tried a copy and paste Macro, based on a quantity column counting the rows that include text. This gave the desired amount of client names in a new sheet but I was unable to work out how to include the "concatenate" part of this problem to it.
Public Sub CopyData()
' This routing will copy rows based on the quantity to a new sheet.
Dim rngSinglecell As Range
Dim rngQuantityCells As Range
Dim intCount As Integer
' Set this for the range where the Quantity column exists. This works only if there are no empty cells
Set rngQuantityCells = Range("G1", Range("G1").End(xlDown))
For Each rngSinglecell In rngQuantityCells
' Check if this cell actually contains a number
If IsNumeric(rngSinglecell.Value) Then
' Check if the number is greater than 0
If rngSinglecell.Value > 0 Then
' Copy this row as many times as .value
For intCount = 1 To rngSinglecell.Value
' Copy the row into the next emtpy row in sheet2
Range(rngSinglecell.Address).EntireRow.Copy Destination:=Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1)
' The above line finds the next empty row.
Next
End If
End If
Next
End Sub

If your goal is to get from this:
...to this (or that):
...then what you want to do is called an Unpivot.
How to Unpivot "crosstab-style" data:
You can find the steps written out on a question I answered a week ago, and there's a more detailed explanation and steps over here.
Let me know if you have any questions!
Yeah, maybe I used this as an excuse to practice using Screen2Gif, but it sure helps demo a point! :-)
🇨🇦

Related

Linking rows in the main sheet to automatically created sheet

first of all I've read many topics but none has my solution.
I have a data of 4 columns and N Rows (as N is unknown number).
Here is a sample:
When a new row entered I want it to automatically create new sheet has the name which is written in title column of that row (for the first row, create sheet with name "M")
also copy all data in row M to the new sheet
i know there is a way
=<SheetName>!<cell> but it isn't really helps if i have for example 1000 columns,
i have to create 1000 sheet then copy 1000 times!!
that's all, thanks in advance.
also feel free to use any methods (such as VBA).
I think this could be messy especially if you end up with a lot of Data. The code below will allow you to run a Macro that will quickly create sheets based on the data. This macro will only work once but it does the job
Sub CopyRowsToSheet()
' Variables needed for the formula
Dim NofRows As Long
Dim i As Long
Dim iActive As Boolean
' Counting the number of Rows in the active sheet
With ActiveSheet
NofRows = .Range("A" & Rows.Count).End(xlUp).Row
' Cycling through the number of rows on the active sheet
' we have set i = 2 as there is a header on the first page. If there is no header then set i = 1
For i = 2 To NofRows
' Creating the new sheet
Worksheets.Add(, Sheets(Sheets.Count)).Name = "Row " & i
' Copy Data to new sheet
.Rows(i).Copy Sheets("Row " & i).Range("A1:D1")
Next i
End With
End Sub
Apologies not 100% sure how to make this automatic but if I find a way i will add it here for you

How to create a Macro to compare A1 in 2 worksheets and copy adjacents contents

I have 2 worksheets (WS1 is "ImportWS" and WS2 is "Disco + BLScope", there are names in column A in both worksheets and both have a column B with a value like Jumps high or still cant jump high). I need to compare WS Disco + BLScope column A with ImportWS Column A and if a match is found then copy the adjacent value in WS ImportWS Column "B" to WS Disco + BLScope Column "B" on the respective matched row and then continue to see if there are more updates in WS ImportWSand repeat.
In a perfect-world, a pop up would appear at the end stating how many updates were found/made.
I have tried Vlookups but that doesn't work as I want to keep the value in WS Master if a match is not found.
I found this code (which does the core of what I need) which I tried to adjust but I get a run time error on the "lassrowAdd" line:
Sub CopyAdjacent()
Dim colStatus, lastrowAdd, lastrowRemove As Integer
colStatus = 2
lastrowAdd = Sheets(“ImportWS”).Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lastrowAdd
If Sheets(“ImportWS”).Cells(i, 1).Value = Sheets(“Disco + BLScope”).Cells(i, 1).Value Then
Sheets(“Disco + BLScope”).Cells(i, colStatus).Value = Sheets(“ImportWS”).Cells(i, colStatus).Value
End If
Next
End Sub
So basically the end result would be:
The worksheet Disco + BLScope would have an updated value in the respective column B rows if an update is found in worksheet ImportWS.
At the end of the macro a popup to appear (this is totally optional) stating how many updates were found/made.
Hope that made sense, been trying for hours but cant crack it, your help would very much be appreciated.

Excel fetch rows based on a cell value in another sheet

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.

sort two columns on excel while keeping blank cells

So I trying to sort a list of names that have favorite colors to each of those names. In other words I want to have the sort look like the following example: (A and B correspond columns while #'s correspond rows)
**A** **B** **A** **B**
1 Tim Red 1 Josh Black
2 Blue 2 Yellow
3 Purple 3 Maria Grey
4 Josh Yellow 4 Orange
5 Black 5 Pink
6 Maria Pink 6 Tim Blue
7 Orange 7 Purple
8 Grey 8 Red
I want it to sort the name first, and wherever that name goes, the colors follow its place and then sort the colors. Is there a way to do this without using VBA since I have no knowledge on how to use VBA. Any help would be very grateful and for the record, this is not for a class assignment.
I am currently using Microsoft Excel 2011 for Mac.
I'm not all that good with worksheet functions and stuff but I don't think you're going to be able to achieve what you want without using VBA.
Assuming Mac VBA is the same as on windows, the following code should get you started.
The Idea: Make a regular sort work by filling the blank 'name' cells and once the sort has completed remove the extra names. I haven't included the code to do the actual sorting but the two methods below should populate the empty cells and also empty them aferwards.
Public Sub InsertDuplicates()
Dim Sheet As Worksheet: Set Sheet = ThisWorkbook.Worksheets("Sheet1")
Dim Current As String: Current = ""
Dim Row As Integer: Row = 1
' Fill the blank cells in the names column
Do
If Sheet.Cells(Row, 2).Value2 = "" Then
' Break out of the loop
Exit Do
End If
If Sheet.Cells(Row, 1).Value2 = "" Then
' No name present, so populate cell with the current name
Sheet.Cells(Row, 1).Value2 = Current
Else
' A name has been found, set it as the current name
Current = Sheet.Cells(Row, 1).Value2
End If
' Goto the next row
Row = Row + 1
Loop
End Sub
Public Sub RemoveDuplicates()
Dim Sheet As Worksheet: Set Sheet = ThisWorkbook.Worksheets("Sheet1")
Dim Current As String: Current = ""
Dim Row As Integer: Row = 1
' Remove unwanted duplicate names in names column
Do
If Sheet.Cells(Row, 2).Value2 = "" Then
' Break out of the loop
Exit Do
End If
If Sheet.Cells(Row, 1).Value2 = Current Then
' Row is a duplicate so empty the value
Sheet.Cells(Row, 1).Value2 = ""
Else
' Row is different from the previous, store the value and continue
Current = Sheet.Cells(Row, 1).Value2
End If
' Goto the next row
Row = Row + 1
Loop
End Sub
Public Sub SortList()
' perform the sort (you can record a macro to get the code required)
End Sub
Public Sub DoIt()
' this is the main macro, call this sub to action a sort.
InsertDuplicates
SortList
RemoveDuplicates
End Sub
This can be done without VBA, using helper columns and a manual sort.
If you want to do this all the time instead of just once, you may want to consider changing your data architecture. Entering the name in a raw data sheet on every row, then build a pivot table that shows the sorted layout you are after.
Steps to do the sort manually:
Insert a header row in row 1 and put in labels for each column, i.e. Name, color.
Add another column and use this formula in cell C2 (copy down):
=IF(ISBLANK(A2),C1,A2)
Copy column C and paste over itself with Paste Special > Values. Now there are the names only in this column.
Use the sort dialog to sort by the new column first and by the color second. These are the settings before confirming the sort:
After the sort, you will see this:
Add another formula column with this formula starting in D2 and copied down:
=IF(C2<>C1,C2,"")
Copy column D, paste as values over column A. Delete the helper columns.

Copy several rows from excel sheet and paste into same row on new excel sheet

Could anyone provide some VBA code please that would facilitate the following request?
I would like to copy six rows and paste these into a new sheet on the same row. I have hundreds of rows, hence the request for code. It would need to copy the first six rows to one row, the next six to the second row etc. Each row to be copied has nine cells as in the example below.
ColA |ColB |ColC|ColD|ColE|ColF|ColG|ColH|ColI
Separatecombined|Smoothedremoved|1.00|1.00|99 |90 |95 |98 |accuracy
Many thanks.
Andy
This site exists to allow programmers to help other programmers develop their skills. Sometimes significant pieces of code are provided in answers but this is not a free coding site.
The macro to perform the actions you require is so small and simple, I do not believe you know any VBA at all. Normally I would respond to a question like this by telling you how to write the macro you seek. However, your requirement is so simple it was easier to code than to provide instructions. you must learn VBA if you want to use macros. It will not take long to learn the basics and the time spent will quickly repay itself. Search for "VBA Excel tutorial". There are many to choose from. Try a few and complete the one that matches your learning style. I prefer books. I visited a large library and reviewed all the Excel VBA primers. I then bought the one I preferred.
The first task is to find the last used row in the source worksheet. I have used the method that is normally the most convenient. However, there are several method of finding the last row or column and none work in every situation. The method I have chosen may not work with your data. This answer of mine includes a macro, FindFinal, which uses a variety of methods and shows when they fail. This will help you choose an alternative if necessary.
You then need nested for loops to move the data.
The macro below is the one you asked for but I am not sure it is the macro you want. If I had your requirement, I would want source row 1 (the column headings) duplicated six times and then rows 2 to last copied across. I leave you with the task of creating a copy of my inner loop to achieve this duplication. Come back with questions if necessary but I believe forcing you to make this amendment will help you understand my code and help you develop your own skills.
Good luck and welcome to the joys of programming.
Option Explicit
Sub MergeRows()
Dim ColDestCrnt As Long
Dim RowDestCrnt As Long
Dim RowSrcCrnt As Long
Dim RowSrcLast As Long
Dim RowWithinGroupNum As Long
Dim WshtDest As Worksheet
Application.ScreenUpdating = False
Set WshtDest = Worksheets("Destination")
With Worksheets("Source")
' Find last used row of worksheet. This assumes column "A"
' contains a value in every used row.
RowSrcLast = .Cells(Rows.Count, "A").End(xlUp).Row
RowDestCrnt = 1
' Loop for each set of six rows. Unless the source worksheet
' contains a multiple of six rows, the last set will involve the
' copying of empty rows. I decided it was less effort to copy
' these empty rows than to include code to not copy them
For RowSrcCrnt = 1 To RowSrcLast Step 6
' Loop for each row within a set
For RowWithinGroupNum = 0 To 5
' Calculate the start column in the destination worksheet
ColDestCrnt = (RowWithinGroupNum) * 6 + 1
' Copy all six cells from the current source row to the six cells
' starting at the appropriate column in the destination row
.Range(.Cells(RowSrcCrnt + RowWithinGroupNum, 1), _
.Cells(RowSrcCrnt + RowWithinGroupNum, 6)).Copy _
Destination:=WshtDest.Cells(RowDestCrnt, ColDestCrnt)
Next RowWithinGroupNum
' Step the destination row ready for the next set
RowDestCrnt = RowDestCrnt + 1
Next RowSrcCrnt
End With
End Sub

Resources