Excel Formula =Ax&Bx&Cx&Dx... when merged cell appears - vba

I'm working with big table with structure similar to picture below, but more columns(A-AZ) and really more rows. And for some reason I need to get whole row into one string, like you can see as "Expected result", but I'm getting really bad data. Do you know how to get right results? Without VBA, if possible
OK, I don't know how to close this question, but I'm closing it by this. I'm using merged cells, because it's required to use them, and everybody here yells, that merged cells are evil so this question is closed as unsolvable.

To expand on the comments from mattdeak and Brad, the issue is that cells A3:A6 are merged. As a result, the value "Lamp" is actually only in cell A3, and cells A4:A6 are blank. Therefore, J4 sees A4="" and B4="", giving you the indicated result (only the value in C4).
The easiest way, as the commenters noted, is to unmerge the cells and copy all the data into each row. If your cells have to stay merged, I recommend the approach used in this answer. Here's how it works:
Pick a space where you can add a second set of Table columns. I'll use CA since you said you have columns A-AZ.
In CA3, enter the formula =IF(ISBLANK(A3),CA2,A3).
Fill right from CA3 through DZ3. DZ3 should thus refer to AZ3.
Fill down CA3:DZ3 for as many rows as you have. At this point. CA3:DZ<last row> is a copy of your table with everything filled in.
Update the formula to be =CA3 & CB3 & ... for however many columns you need to merge. Use the values from CA:DZ and you should be OK!

If you can use a little VBA, you can create a User Function in a public module as follow:
Public Function MergedValue(r As Range) As Range
Application.Volatile
If Not r.MergeCells Then
Set MergedValue = r
Else
Set MergedValue = r.MergeArea.Cells(1, 1)
End If
End Function
Then replace all =Ax & Bx & Cx ... formulas by =MergedValue(Ax) & MergedValue(Bx) & MergedValue(Cx) ...
Edit: Added Application.Volatile at the start
Edit 2: Without using Application.Volatile
Public Function MergedValue(r As Range, RangeToCheck as range) As Range
If Not r.MergeCells Then
Set MergedValue = r
Else
Set MergedValue = r.MergeArea.Cells(1, 1)
End If
End Function
Call it with =MergedValue(A1,$A$1:$C$3) for example if you want to check cells in range [A1:C3].

=concat(offset(A3,-mod(row()+3,6),,4)) & concat(offset(B3, -mod(row()+1,2),,2)) & C3 & concat(offset(D3,-mod(row()+3,6),,4)) & concat(offset(E3, -mod(row()+1,2),,2)) & concat(offset(F3, -mod(row()+1,2),,2))
to get A column: in j3, -mod(row()+3,6) = 0. so concat(offset(A3,0,0,4)) = A3&A4&A5&A6 = A3.
to get B column: in j3, -mod(row()+1,2) = 0. so cancat(offset(B3,0,0,2)) = B3&B4 = B3.
And so on D, E, F column.
There is another method (writed on 2016/6/20)
step 1.Select A3 cell and press Ctrl + A.
step 2.Then press Ctrl + 1 (The "1" key with "!", Not the "1" in number pad)
step 3.Select "Alignment" tag, disable "Merge Cells"
step 4.Then "Home" -> "Find & Select" -> "Go to special" -> select "Blanks" (the short cut key sequence is: Alt -> h -> f -> d -> s -> k -> Enter)
step 5.The active cell be B4, then write =b3 and press ctrl + Enter
step 6.Then in J3 cell write down: =CONCATENATE(A3,B3,C3,D3,E3,F3) or =CONCAT(A3:F3)

Related

Excel VBA deleting certain rows with certain conditions

I found a code online which works but I am failing to change it for my purpose. Each entry in my spreadsheet contains different formulas as well as an Iferror function with the aim of making cells with error messages appear as blank. For example lets say a cell E3 is dependent on cell F3 with a certain formula (for clarification lets say F3/2.5). It is obvious if there is no entry in cell F3 then an error message would display in cell E3. For this reason, I use the IFERROR function to display the cell as blank. The difficulty arises when I want to delete blank rows after a click on the macro button. However, since that cell does have an entry (a formula which in turn returns an error message), that cell does not delete. Also I need to run this code over 3 different selection ranges. Please can someone help! The code I found was from a different thread on this forum and is:
`sub foo()
dim r As Range, rows As Long, i As Long
Set r = ActiveSheet.Range("A1:Z50")
rows = r.rows.Count
For i = rows To 1 Step (-1)
If WorksheetFunction.CountA(r.rows(i)) = 0 Then r.rows(i).Delete
Next
End Sub`
Thanks Alot!
EDIT: If statement added to the autofilter as it was deleting a row when there were no blanks
You will want to set up a column in the spreadsheet with the following sumproduct:
=SUMPRODUCT((LEN(A1:F1)>0)*1)
This is calculating how many cells' values have a length more than 0 hence are not blank, you will need to adjust cell references accordingly as I tested on a small sample of fake data.
Following this you can just loop:
For i = rows To 1 Step (-1)
If Cells(i,"G") = 0 Then r.rows(i).Delete 'My formula is in column "G"
Next
Or set up an auto-filter and delete entire rows of the visible cells:
Dim lrow As Integer
If Not WorksheetFunction.CountIf(Range("G:G"), "0") = 0 Then
Range("A1:G1").AutoFilter
Range("A1:G1").AutoFilter Field:=7, Criteria1:="0"
lrow = Cells(rows.Count, 7).End(xlUp).Row + 1
Range("G2:G" & lrow).SpecialCells(xlCellTypeVisible).EntireRow.Delete
Range("A1:G1").AutoFilter
End If
The only problem with using a leading column to calculate for this is if you have a lot of data coming and going as you will need to replenish the formula, though you could use auto complete in the code i guess.

Excel Referencing cell entries for use in formula

I'm not sure exactly what to call what I'm trying to do, so searching it has been tough. Basically I have a table of equations, each row has a different equations/references a different column, but all of them reference the same range of rows. i.e. Eq. A = average(A200:A400), Eq. B = sum(C200:C400), etc...
From file to file the range of rows changes, so what I want to do is be able to do is enter the start and end rows into cells and have them auto populate the equations. If anyone could tell me how to do it just for one cell and not an entire table, I could figure it out from there.
Thanks!
Sounds like the INDIRECT function would accomplish this. It allows you to enter in text to be interpreted as a cell reference.
For instance, lets say you wanted the range to cover A200:A400 for a given sheet, and you wanted that desginated in cell A1 of that sheet. In cell A1 you would just type in "A200:A400" then, in the actual equations, you would have:
=AVERAGE(INDIRECT(A1))
You can obviously split this further down, but thats the concept of it.
You could create a form with a few text boxes. Enter the start and end row. Then your code could go through and enter the formula.
Something like this.
Dim lRow as long
Dim lEnd as long
lRow = val(txtBoxStartRow.text)
lEnd = val(txtBoxEndRow.text)
ws.Range("A" & lEnd + 1).Formula = "=average(A" & lRow & ":A" & lEnd & ")"
ws.Range("C" & lEnd + 1).Formula = "=average(C" & lRow & ":C" & lEnd & ")"
This should do:
=AVERAGE(INDIRECT(ADDRESS($B$1;ROW())):INDIRECT(ADDRESS($B$2;ROW())))
In that code I'm assuming cells B1 and B2 contain the limits (you can replace these references with hard number), to use your example: B1 = 200 and B2 = 400.
If you then place this code in any row, you'd get average("rowNumber"200:"rowNumber"400).
Address() gives you the right range reference
Indirect() makes a range out of it
Then you can wrap it in whatever function you like.

Selecting every Nth row, Excel. Replace with nothing or original cell content

I've got an Excel sheet with my variables listed in column E and their values listed in column G
I would like to test if E contains the word "text" (my variable). If so then I want to replace the corresponding cell in column G with "This is my successful if statement text".
If not -- I want the cell to either be left alone (impossible in excel) or keep the value it originally had (I think the issue is its populated with text not numbers).
So far ive tried
=if(e2="text", "Replace with this", G2)
as well as
=if(e2="text", "replace with this", "")
The top returns a number while the bottom returns an empty cell which deletes the contents I had there.
Any suggestions? I think this can be done with VB but that's out of my league.
The proper way to solve this is as so.
In column H (or any that doesn't contain any information) place the formula
=IF(E2 = "text", "This is the true part", G2) and drag down.
This will test E2 for the word "text" and then replace with "this is true.." If the conditions are not met, the original text from G2 is pulled into the new column.
Once this is complete, the desired results should have taken effect. You can then copy the row and use "Paste Special" and select "Values" from the pop up menu to paste in your new data. Selecting Values allows the user to paste the actual field data, not the formula that generated it!
Try this.
Sub g()
Dim ws As Worksheet
Dim lastRow As Long
Set ws = ThisWorkbook.Worksheets("Sheet1") 'change sheet name as applicable
lastRow = ws.Cells(ws.Rows.Count, "E").End(xlUp).Row
For i = 1 To lastRow
With ws
If .Cells(i, 5) = "text" Then
.Cells(i, 7) = "The text you want"
End If
End With
Next
End Sub
It seems like you are trying to get four values from column E that you want to parse (cut up) and place in Column G.
By creating four parses { =mid(e2,16,10), =mid(e3, 9, 15), =mid(e4,5,3), =mid(e5,10,22) } in cells G2, G3, G4, and G5, respectively, you can select the block of four G cells (G2:G5), select the block at the bottom right, and drag it down throughout the file.
Optionally, you can use modulo math and case statements to loop through the file and perform the required function at each point:
myCount = 0
myLoop = 0
endMyLoop = false
range("G2").activate
do
myLoop = myCount mod 4
select case myLoop
case 0
code for description_tag
case 1
code for title_tag
case 2
code for headline
case 3
code for text
end select
if activecell.value = "" then endMyLoop = true
loop until (endMyLoop = true)
You stated that every fourth row the value in E is text. So, it should just be a matter of copying the formula every fourth row or performing your function every fourth iteration (modulo returns the remainder) in the G column.
One other option would be to nest your if loops (=if(e2="text","Its text",if(e2="title_tag","Its a title",if(e2="headline","Its headline","Its description")))) to account for the four different options. Of course you would fill the text with the function that you actually want to perform.

VBA applying function to each cell in range

I need to write macro or function or whatever in VBA, what will apply a function with arguments (e.g. vlookup) on a rangeof cells. I thought it can be done by macro, but there I could not use arguments for vlookup, so I dont know any way how to do it. Is it possible?
For example:
I want to have this:
vlookup(A1;G1:H50;2;0) in cell B1 and
vlookup(A2;G1:H50;2;0) in cell B2 and so on, to e.g. B10
but I want to write formula only once and let other cells to be filled automaticaly.
Thanks a lot.
If I understand you correctly, here is one way (you'll have to change the delimiter to match your country settings, and adjust where you want the formula to go, I just put in B1:B10 as an example):
Sheet1.Range("B1:B10").Formula = "=vlookup(A1,$G$1:$H$50,2,0)"
This bit of code will write the formula to the range B1:B10 on sheet1, which has the same effect of putting the formula in the B1 and then "dragging" it down to B10. What makes this work is that Excel has the built in functionality of auto-incrementing a formula references based on whether or not the range is preceded by a $ symbol.
If a column reference has a $ in front, it will not increment as the formula is dragged across columns. If the $ is in front of the row reference, it will not increment as the formula is dragged down.
So looking back at my proposed formula, you can see that the A1 will increment as the formula is dragged to B2, B3, B4, etc...auto-incrementing the look up value to be cell A2, A3, A4, respectively. The look up range does not change at all because both the column and the row references are preceded by a $.
If you run the code I gave you, you'll see that you should have the expected results of only writing one formula, but changing the look up range through the built in auto incrementing functionality.
--------------------More edits based on comments--------------------
To do what you want, you don't need VBA at all (even though you initially requested a VBA / macro solution). You can put the formula in a cell and drag it down to how ever far down you want it to go. Please take a look at this link to see if it helps answer your questions:
How to fill data automatically in Excel
You could use Application.VLookup just like this following this example http://www.exceltrick.com/formulas_macros/vlookup-in-vba/:
Sub SetValues(columnToChange As String, columnToLookup As String, range As String, startColumn As Integer, endColumn As Integer)
For number = startColumn To endColumn Step 1
valueLookup = columnToLookup + CStr(number)
valueToChange = columnToChange + CStr(number)
Sheets("yourSheetName").Range(valueToChange).value = Application.VLookup(valueLookup, range, 2, 0)
Next number
End Sub
If you want to call them, create another subroutine without parameters that you can call from a button click for instance.
Sub DoStuff()
On Error GoTo ErrorHandler
Dim valueLookup as String
Dim valueToChange as String
Dim range as String
Dim firstColumn as Integer
Dim lastColumn as Integer
Label1:
valueLookup = InputBox("Enter the column to lookup")
valueToChange = InputBox("Enter the column to change")
range = InputBox("Enter the range of the lookup")
firstColumn = CInt(InputBox("Enter the first column number to lookup"))
lastColumn = CInt(InputBox("Enter the last column number to lookup"))
Call SetValues(valueToChange, valueLookup, range, firstColumn, lastColumn)
Exit Sub
ErrorHandler:
MsgBox("One value has an error in it.")
Resume Label1:
End Sub

Excel pulling data from certain cells

I have a file that I only want to extract cells B9, B19, B29, etc etc etc in a pattern throughout the entire file. I would preferably like it to be extracted to a different excel file or someway so that I can do stuff with only those cells in another excel worksheet.
Potentially, I may have several excel files that I may need to do this sort of thing so if there were a way where I had the same format throughout a lot of files that I could always extract cells B9, B19, B29 that would be great. any help appreciated
I looking for syntax if possible
EDIT
Was thinking if I could somehow make an excel IF statement saying if Row has a 9 in it and the row is B then print it somewhere but I want it printed in a column
EDIT 2
I just want column B not A like I mentioned before.
B9, B19,B29,B39 through the whole file
Just in case you want to do it with code:
Sub Test()
'Assumes Sheet1 has your values and Sheet2 will be the data extracted from every row ending in 9
Dim iCounter As Long
Dim newSheetRow As Long
Dim aValue As String
Dim bValue As String
newSheetRow = 1
'Start and nine and increment by 10 till you reach end of sheet
For iCounter = 9 To Sheet1.Rows.Count - 1 Step 10 'NOTE: You may not want to do it by RowCount, but just showing you could
aValue = Sheet1.Range("A" & iCounter)
bValue = Sheet1.Range("B" & iCounter)
Sheet2.Range("A" & newSheetRow).Value = "We were on row: " & iCounter
Sheet2.Range("B" & newSheetRow).Value = aValue
Sheet2.Range("C" & newSheetRow).Value = bValue
newSheetRow = newSheetRow + 1
Next iCounter
MsgBox "Done"
End Sub
You could use the INDIRECT function. It takes a cell reference as a text string and returns the value in that cell. So instead of using
=data!a9
to get the value in sheet "data" in cell a9, you use
=indirect("data!a9")
You can also use r1c1 notation, like this:
=indirect("data!r9c1",false)
From there you can use the ROW and COLUMN functions to go in steps of 10:
=INDIRECT("data!r"&-1+10*ROW()&"c"&COLUMN(),FALSE)
If you put this formula in A1 of your output sheet and then copy and paste it down and across, it will give you the values in data!A9, data!A19, data!A29,... in cells A1, A2, A3... Depending on how you want your output arranged, you might have to modify the cell reference string.
Depending on how often you want to do this depends on how you need to do it, if it's a one of them some simple excel commands might help.
e.g.
In Cell C1 put the following:
=MOD(ROW(),10)
then replicate this down to the bottom of your data. the command will return the numbers 1 through to 0. You can then filter the data on column C where value is 9 then select the visible rows and copy the data to a new sheet.
ROW() ' this returns the ROW number of cell the command is in.
MOD(number, divisor) ' this basically divides one number by the other and returns the remainder. so row 9 / 10 = 0 remainder of 9, row 19 / 10 = 1 remainder of 9.
Hope this helps.