What I'm trying to do is very simple, I just don't have much VBA / Excel experience to know how to do it.
I am working on a macro to do a few different things, I'm just stuck on this part.
What I want to do is go through all of my rows, and if the first cell in the row is empty, I want to select the entire row and UnMerge it. I know that if the first cell is empty, that row contains merged cells that I want unmerged.
I know that these two lines below will select row 2 and Unmerge it, but I need a way to loop through my data and find and unmerge the rows automatically, because the row numbers wont be the same every time.
Rows("2:2").Select
Selection.UnMerge
I want to do something like this:
For (each row) {
if (the first cell is empty) {
UnMerge all cells in that row;
}
}
I just don't know how to do that in VBA syntax.
Any help is appreciated!
This should do the job.
Sub UnmergeRows()
Dim R As Long ' loop counter: rows
With Worksheets("Sheet1") ' change tab name as required
' "B" should be the longest column in the worksheet
For R = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row
If IsEmpty(.Cells(R, 1)) Then .Rows(R).MergeCells = False
Next R
End With
End Sub
I have a problem with a vba macro that i can't seem to find the answer to anywhere. Feels like i've tried everyting so i'll put the question out there to see if anyone here can help me :)
My macro loops through 50 woorkbooks that all have a "Firstpage" where the data from all the other data worksheets are summarized. In that Firstpage i have a table called "Tabell_1". The table has a header row (B4:F4) and then one row for each data worksheet in the workbook and the a sum row. We have decided to add a new column (column D) to the table to add in data from a specific cell in all the other worksheets (B4).
I now loop through the data worksheets to copy the value in B4 and then i want to paste that value to the first empty row in the table on the "Firstpage" (starting from the cell under the header). The method to find the last row that i use in other parts of the macro doesn't work, it gives me the first row after the sum row and then pastes the values under the table.
The picture shows the table that i'm working with for one of the workbooks.
enter image description here
Hej Johanna!
Assuming that you are using listobjects to manage the data I would just do this..
Sub Test2()
Dim lo As ListObject
Dim lr As ListRow
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set lo = ws.ListObjects("Tabell_1")
Count = 1
For Each lr In lo.ListRows
If lo.ListColumns("Test2").DataBodyRange(lr.Index) = "" Then
lo.ListColumns("Test2").DataBodyRange(lr.Index) = Count
Count = Count + 1
End If
Next lr
End Sub
This is will fill the first empty row in column Test2.
Hopefully you can use this example :)
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
I have some data in a worksheet in a single row (row 44) where the required data is in columns C,F,I,L and so on (i.e. data required every 3rd column starting from C).
This ends at column 'ET'
I need to extract this and paste it into another worksheet row where there are no column spaces.
I've looked around for solutions but its usually columns but this is data i need in one row.
Assuming this needs to be done even when the data in row 44 changes, you could do a macro. In a procedure, the following code could work as a guideline:
Public Sub copyover()
Dim c As Long
For c = 1 To 50
Worksheets("Sheet2").Cells(1, c).Value = _
Worksheets("Sheet1").Cells(44, c * 3).Value
Next
End Sub
Does this have to be a macro? Put this in the first destination cell on the other worksheet:
=INDEX(Sheet1!$C$44:$ET$44,1,3*(COLUMN(A1)-1)+1)
Then copy right
I have a row of data as follows:
header1 header2 header3 header4 header5
row key datavalue1 datavalue2 datavalue3 datavalue4 datavalue5....
so basically, I have a denormalized data set where the datavalues may or may not be empty on a row-by-row basis. I need to normalize them.
ie
12345678 NULL 10 3 NULL 14
would become:
12345678 header2 10
12345678 header3 3
12345678 header5 14
I could do this by using a paste special transform, but I have thousands of rows and I'd need to make sure that I get the right row key for each. furthermore, each row has a bunch of descriptives associated with it that I need copied over with each datavalue.
What is the easiest way to convert each row of columns such that I have multiple rows of a single column with all non-empty datavalues plus the associated datavalue reference? I need to be able to pivot the dataset.
If you have five "header" columns, enter these formulas
H1: =OFFSET($A$1,INT((ROW()-1)/5)+1,0)
I1: =OFFSET($A$1,0,IF(MOD(ROW(),5)=0,5,MOD(ROW(),5)))
J1: =INDEX($A$1:$F$9,MATCH(H1,$A$1:$A$9,FALSE),MATCH(I1,$A$1:$F$1,FALSE))
Copy H1:J?? and paste special values over the top. Sort on column J and delete anything that's a zero. If you have legitmate zeros in the data, then you first need to replace blank cells with some unique string that you can then delete later.
If you have more columns, then replace the '5' in all the above formulas with whatever number you have.
Seems to me that part of what you are trying to do is to "de-pivot" a pivot table. I've found this tip to be a tremendous help when I've had to do similar tasks: http://spreadsheetpage.com/index.php/tip/creating_a_database_table_from_a_summary_table/
Note that in Excel 2007, you can get to the old Excel 2003 pivot table wizard using the keystrokes Alt+D, P .
Excel has a transpose feature which may address your needs. It's pretty hidden and a bit clumsy but likely easier than delving into VBA. Here's an excerpt from Excel 2007 Help:
Blockquote
Switch (transpose) columns and rows
Show AllHide All
If data is entered in columns or rows, but you want to rearrange that data into rows or columns instead, you can quickly transpose the data from one to the other.
For example, the regional sales data that is organized in columns appears in rows after transposing the data, as shown in the following graphics.
1.On the worksheet, do the following:
To rearrange data from columns to rows, select the cells in the columns that contain the data.
To rearrange data from rows to columns, select the cells in the rows that contain the data.
2.On the Home tab, in the Clipboard group, click Copy .
Keyboard shortcut To copy the selected data, you can also press CTRL+C.
Note You can only use the Copy command to rearrange the data. To complete this procedure successfully, do not use the Cut command.
3.On the worksheet, select the first cell of the destination rows or columns into which you want to rearrange the copied data.
Note Copy areas (copy area: The cells that you copy when you want to paste data into another location. After you copy cells, a moving border appears around them to indicate that they've been copied.) and paste areas (paste area: The target destination for data that's been cut or copied by using the Office Clipboard.) cannot overlap. Make sure that you select a cell in a paste area that falls outside of the area from which you copied the data.
4.On the Home tab, in the Clipboard group, click the arrow below Paste, and then click Transpose.
5.After the data is transposed successfully, you can delete the data in the copy area.
Tip If the cells that you transpose contain formulas, the formulas are transposed and cell references to data in transposed cells are automatically adjusted. To make sure that formulas continue to refer correctly to data in nontransposed cells, use absolute references in the formulas before you transpose them.
For more information, see Switch between relative, absolute, and mixed references.
Blockquote
Let's look at a possible solution in VBA. I think this will really help. Here are a few things you should know about my code.
You'll need to put this code in a code module in VBA (the same place where Macros go)
Look at what I named the sheets: Original and Normalized. You'll either want to change your sheet names or the code
I'm checking for values with a string field of NULL. If the cell is empty, you'll want to check for If IsEmpty(rngCurrent.Value) Then instead.
'
Sub NormalizeSheet()
Dim wsOriginal As Worksheet
Dim wsNormalized As Worksheet
Dim strKey As String
Dim clnHeader As Collection
Dim lngColumnCounter As Long
Dim lngRowCounterOriginal As Long
Dim lngRowCounterNormalized As Long
Dim rngCurrent As Range
Dim varColumn As Variant
Set wsOriginal = ThisWorkbook.Worksheets("Original") 'This is the name of your original worksheet'
Set wsNormalized = ThisWorkbook.Worksheets("Normalized") 'This is the name of the new worksheet'
Set clnHeader = New Collection
wsNormalized.Cells.ClearContents 'This deletes the contents of the destination worksheet'
lngColumnCounter = 2
lngRowCounterOriginal = 1
Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
' We'll loop through just the headers to get a collection of header names'
Do Until IsEmpty(rngCurrent.Value)
clnHeader.Add rngCurrent.Value, CStr(lngColumnCounter)
lngColumnCounter = lngColumnCounter + 1
Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
Loop
'Here we'll reset our Row Counter and loop through the entire data set'
lngRowCounterOriginal = 2
lngRowCounterNormalized = 1
lngColumnCounter = 1
Do While Not IsEmpty(wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter))
Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
strKey = rngCurrent.Value ' Get the key value from the current cell'
lngColumnCounter = 2
'This next loop parses the denormalized values for each row'
Do While Not IsEmpty(wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter))
Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
'We're going to check to see if the current value'
'is equal to NULL. If it is, we won't add it to'
'the Normalized Table.'
If rngCurrent.Value = "NULL" Then
'Skip it'
Else
'Add this item to the normalized sheet'
wsNormalized.Range("A" & lngRowCounterNormalized).Value = strKey
wsNormalized.Range("B" & lngRowCounterNormalized).Value = clnHeader(CStr(lngColumnCounter))
wsNormalized.Range("C" & lngRowCounterNormalized).Value = rngCurrent.Value
lngRowCounterNormalized = lngRowCounterNormalized + 1
End If
lngColumnCounter = lngColumnCounter + 1
Loop
lngRowCounterOriginal = lngRowCounterOriginal + 1
lngColumnCounter = 1 'We reset the column counter here because we're on a new row'
Loop
End Sub
I would create a VBA macro that loops through each row and output the data to another page. This would let you create your pivot table in the new page once the data has been outputed.
Not sure how familiar you are with VBA, but this could pretty easily be done by loading the data into an array (or collection of objects if you really want to do it correctly) and writing it back out.
Here is a link to a good VBA document.
http://social.msdn.microsoft.com/Forums/en/isvvba/thread/d712dbdd-c876-4fe2-86d2-7d6323b4262c
Edit
Please note this is not meant to be a fully working solution but really a generic framework to help you in the right direction.
As a generic example that does a lot of what you would need to do (not the best way, but probably the easiest for a beginer), something like this should get you started, although it is hard to say without seeing more of your worksheet.
Sub RowsToColumns ()
Application.ScreenUpdating = False
Dim srcWrkSheet As Worksheet
Dim destWrkSheet As Worksheet
Dim excelData as pExcelData
Dim srcRowNumber As Long
Dim srcRolNumber As Long
Dim destRowNumber As Long
Dim destColNumber As Long
SET srcWrkSheet = Sheets("YourSourceWorkSheetName")
SET destWrkSheet = Sheets("YourDestinationWorkSheetName")
srcRowNumber = 1
srcColNumber = 1
destRowNumber = 1
destColNumber = 1
'Loop until blank row is encountered in column 1
Do
destWrkSheet.Cells(destRowNumber ,1).Value = "Header 1 " & srcWrkSheet.Cells(srcRowNumber,srcColNumber )
destWrkSheet.Cells(destRowNumber ,1).Value = "Header 2 " & srcWrkSheet.Cells(srcRowNumber ,srcColNumber)
srcRowNumber = srcRowNumber + 1
srcColNumber = srcColNumber + 1
destRowNumber = destRowNumber + 1
Loop Until srcWrkSheet .Cells(rowNumber, 1).value = ""
End Sub