I have a table in word in which I merge 1 cell with text to the 2 empty cells left of it. Each time it merges it adds a new line under the text of the merged cell. This messes up the whole layout of the table. This table has been copied from Excel and pasted into Word. How do I fix this?
Dim table1 as Table
With table1
.Cell(Row:=1, Column:=3).Merge _
MergeTo:=.Cell(Row:=1, Column:=5)
End With
This variation includes two solutions for how to deal with existing content in cells being merged.
Private Sub TestMerge()
Dim i As Long
With ActiveDocument.Tables(1).Rows(1)
For i = 3 To 4
' .Cells(i).Range.Text = ""
.Cells(2).Merge .Cells(i)
Next i
.Cells(2).Range.Text = ""
End With
End Sub
The first solution deletes everything in cells 3 and 4 but retains content of cell(2). In the above code it is rendered mute by the apostrophe preceding the code.
The second way is to remove everything from the merged cells. I would recommend to run this version only while Application.ScreenUpdating = False because it will cause a lot of flicker.
There are several more way, but in order to recommend the one most suitable for your needs one would need to have a better understanding of what you want. BTW, if at all possible, remove the blanks from the table at the time they are entered. Having blanks floating around your document and popping up when they are least expected or wanted is never a good idea.
The Merge command can only merge two adjacent cells. You might use a loop to merge more cells.
Dim i As Long
With ActiveDocument.Tables(1).Rows(1)
For i = 3 To 4
.Cells(2).Merge .Cells(i)
Next i
End With
Cells 3 and 4 are merged with cell(2).
Related
I converted a few files containing huge price lists from *.pdf to *.xls format using an online file format converter. However the conversion didn't give the desired result and more cleanup work is needed on the file. Have tried various different approaches using the macro recorder and tack overflow and have failed.
I need a macro that does the following cleanup work on my data.
Loops through rows in the selected data and Search for incomplete rows that are missing an entry in one or more cells.
Concatenate the text in these incomplete rows with the cell in the same column in the first complete row above it.
Example;
If row A contains all entries, but row B is missing entry in the Product code column then the entry in the needle description column in row B should concatenate with the needle description in row A
This file contain 10 line of data. Tab 1 shows the data that contains incomplete rows for the first 2 products. Tab 2 shows the form i want it to be in.
http://www.filetolink.com/5e39eaaf00
I'd be very grateful for any help on this for it will save me a lot of head wringing.
I didn't pull up the file because that site has extreme safety risk warnings, but the below code will do what you want as far as I can tell. If not, please clarify and I'll modify as necessary.
My Excel columns are in the following order:
ID, ProductCode, NeedleDescription
If your NeedleDescription isn't the first column to the right of your ProductCode this won't work. Just let me know what order your columns are in and I'll modify as necessary.
Copy the below into a module
Highlight the range you desire to clean up
Run the macro "Cleanse"
It will loop through all rows and fill all empty cells with the concatenation of:
CurrentRowNeedleDescription & PreviousRowNeedleDescription
Sub Cleanse()
'Fill an empty or blank cell in selection
'with formula specified
'First Highlight Affected Range, then run this macro
Dim cell As Range
On Error Resume Next
'Set formula to include in empty cells
'to be the description of existing row plus description of previous row
'Test for empty cell. If empty, fill cell with value given
For Each cell In Selection
If IsEmpty(cell) Then
cell.FormulaR1C1 = "=RC[1]&R[-1]C[1]"
End If
Next
End Sub
Hope that helps!
I am trying to add to a macro I have that will hide every row that has no text in a column named Authorization. Please see the code I have below, I thought this may be on the right track but it does not hide any rows.
Cells.EntireRow.Hidden = False
For Each cell In Range("Authorization").End(xlUp)
If cell = "" And cell.Offset(1, 0) = "" Then cell.EntireRow.Hidden = True
Next cell
Edited to add how to define a dynamic named range
It is the fact that you have set the whole column to the name "Authorisation" that I think makes your code freeze, because the whole column is 1 million rows (if you have 2007 or above), and the code will still check even blank rows, so its doing it 1 million times. 1 Option is to rather than set it to the whole column, you could use a "Dynamic Named Range" which will expand and grow as data is added. There are several different formulas to do this, but based on the fact your data may contain blanks, this version of the formula will expand down to the last populated row in the column. My example uses colum A as you havent specified what column you are using, so change A to suit your needs.
You need to open the Names manager, from the Formulas tab
From the dialog box, find your "Authorisation" name.
Select it and you should see its current formula at the bottom of the dialog box, replace that with the following formula:
=OFFSET(Sheet1!$A$3,0,0,MATCH("*",Sheet1!$A:$A,-1)-2,1)
In the above formula:
Sheet1 is my sheet, replace it with yours a needed
$A$3 is the starting row of the name, so based on your comments, have set this as column A row 3
0,0, Are defaults you should not need to change
$A$A$ is the column it is counting values, so change as required
-1 is a default, leave as is
-2 is subtracting 2 from the count because we are starting on row 3, so if you change the starting row, change this
the last 1, defined how many columns your named range covers, in your example it is just 1, so this should not need changing.
Once you have defined the name in this way, the code below should work a lot quicker as it will only loop through down to the last row of entered data. There is one possible issue I can see with this and that is if the very last cell in column A is blank, but the rest of the row isn't, this will miss out the last row. I could fix this by using a different column to count what constitutes the last row, but need to know whicj column would always have a value in it.
< Original answer and code>
not sure you code matches the description of what you want it to do, namely you seem to be trying to check the row beneath the current cell as well, is this what you really wanted? Anyhow your syntax is slightly wrong. I have written and tested this and it works, I have swapped your offset around so my code is checking the cell in the named range "Authorisation" and then also checking the cell to the right. Amend to suit your needs
Sub test()
Dim c As Range
For Each c In Range("Authorisation").Cells
If c.Value = "" And c.Offset(0, 1).Value = "" Then c.EntireRow.Hidden = True
Next c
End Sub
I have a SAP Report embedded in a worksheet, it is refreshed via a macro using variables defined in another worksheet. That all works fine, but i am having trouble selecting the data the report generates.
The headings of the report are in and always will fall in this range ("A17:K17"), but the results rows will vary making the total range I want to capture anywhere from ("A17:K18") to (A17:K1000").
The solutions I've already tried didn't work i think because there is almost no consistency in the result data, it's a mixture of text and numbers with empty cells all over the place, in both the rows and columns. Including the occasional completely empty row. This means the methods I have tried before reach a point where it thinks it's reached the end of the populated rows - but it hasn't.
The only factor that remains the same throughout the report is that the cells in the range I want to capture are all filled with a color as default and anything outside the range is unfilled.
To me the simplest solution would be to use VBA to select all the cells beneath and including the headers on ("A17:K17") where the color index is not 0 (blank?) regardless of their contents as I don't mind capturing empty cells. Except I don't know how to do this.
At this point I'd just like to select this range I haven't decided if I'm going to copy it into a new workbook or into an email yet, but that I can do. I've just hit a dead end selecting it.
Quite unsure exactly what it is you require but here's a solution. It's worth noting that both the ColorIndex and Color properties are not necessarily zero with no fill, so if you just change blankCell to a cell with the fill which you define to be blank you'll be good to go.
Sub test()
Set blankCell = Range("A1") ' change this to a cell that you define to be blank
blankIndex = blankCell.Interior.Color
Set cellsDesired = Range("A17:K17")
For Each cell In Range("A17:K1000")
If cell.Interior.Color <> blankIndex Then
Set cellsDesired = Application.Union(cellsDesired, Range(cell.Address))
End If
Next cell
cellsDesired.Select
End Sub
Is it possible to have the formulas that I need applied on columns be saved or applied to a column header or some kind of metadata so that as and when I add new rows to my Excel table the Formulas get applied to the columns?
Scenarion:
I am creating a template Table, which will have no rows at first.
On a separate sheet (or same sheet for that matter) once the user selects the number of rows to be generated in the table, I dynamically add rows to the table using VBA.
The idea is I may not have any rows in the table at beginning OR user may have deleted rows manually.
When I programmatically add new rows, I want the Formulas applied on the cells as well. Most of the formulas I am using are either of the three types:
Structured table reference, Excel functions like SUM, AVERAGE etc and custom function names.
Updated:
Here is what I have tried:
1> tried applying the formula to the header itself.
Result: The header it self changes with #REF! error. I think the behavior is correct. So it's a no-go option.
2> Tried creating one row and apply the formula to the row. That works, but the problem is, I do not want a dummy row to begin with.
3> Using VBA code to add row to the table using
ActiveWorkbook.Worksheets("Sheet3").ListObjects("Table2").ListRows.Add AlwaysInsert:=True
inside a for loop.
The new rows retain the visual style sheets, but does not seem to retain the formulas. Just blank cells.
Could the fomrmulas be in header cell commnets?
And then with VBA add the formula for the current row:
Sub test()
Dim headerCells As Range
Set headerCells = Range("B2:E2")
OnNewRow 3, headerCells
End Sub
Sub OnNewRow(newRow As Integer, headerCells As Range)
Dim headerCell As Range, targetCell As Range, formulaFromComment As String
For Each headerCell In headerCells
formulaFromComment = GetFormulaFromComment(headerCell)
If (formulaFromComment = "") Then _
GoTo NextHeaderCell
Set targetCell = Intersect(headerCells.Worksheet.Rows(newRow), _
headerCell.EntireColumn)
AddFormula newRow, targetCell, formulaFromComment
NextHeaderCell:
Next
End Sub
Sub AddFormula( _
newRow As Integer, _
targetCell As Range, _
formula As String)
formula = Replace(formula, "{ROW}", newRow)
targetCell.formula = formula
End Sub
Function GetFormulaFromComment(headerCells As Range) As String
' TODO
GetFormulaFromComment = "=SUM($C${ROW}:$E${ROW})"
End Function
Just use tables.
If you highlight cells and choose Insert Table from the ribbon, it doesn't just give you formatting and filters. It also, if you build them the right way, stores column formulas once per column instead of once per cell. Also, the formulas are more readable!
For formulas, you can't use cell addresses if you want it to be a single column formula unless they are absolute. (E.g. $A$1, not A1.) Instead, you use [ColumnTitle] for the entire column (where "ColumnTitle" is the actual title of that column) and [#ColumnTitle] for the column value in the same row. So if "Cost" was the title of column B, "RunningTotal" was the title of column C and your formula for C6 was therefore =B6+C5, you'd instead use a formula of =[#Cost]+OFFSET([#RunningTotal],-1,0)] which is longer but much easier to read/maintain/debug, and if you change a column title then the formulas change too! No VBA required. Given this, plus being able change columns for the entire columns at once, plus being able to refer to other columns in other tables without worrying about cell addresses (e.g. MAX(Table1[Cost])), plus being able to style the tables so easily, plus the integration with Power-Query, and VBA support. (See learn.microsoft.com.) Whether VBA or otherwise, add a row to your table and the columns with a single column formulas will automatically carry over into the new row.
Not sure about Table templates or VBA but perhaps there is another option by using =ARRAYFORMULA()
For example, say you had a header row and 3 columns and wanted your last column to be the product of the first two. In cell C2 you could enter the following:
=ARRAYFORMULA(A2:A*B2:B)
This has three benefits:
Skips the first row completely
Effectively applies the formula to every row which is useful if you later decide to insert a row (your question)
Only one location to modify the formula for every single row
Although, it may not be immediately obvious where how/where the cells are being calculated. (hint: ctrl+~ may help)
Range("H25")
The above statement selects the 25th row of H column.Now The thing I want to know is,
How do i increment the row putting H constant?
yeah I have seen these on the google $h24 where column stays constant and row keeps on incrementing.
But i have to increment it from H25 to the end I dont know where does H column end. how do i make that?We can declare a variable right using VBA and incremenet it?
I was thinkin to put it like these Range("Hvariablename")?
The actual Task I need to do is I have to check rows from H25 to the end and get their values to my VBA and make some calcutaions then right it back to them Im stucked at incrementing the rows.And could anyone please let me know the macro to delete a row from the vba itself?Thank you
I believe you can provide some further details about how this range is supposed to looks like. When you mean "have to check rows from H25 to the end and" what's the END here?
If you're manually copying the formula down, it will automatically goes until the last row with values in column G. Is that your case? I'm not assuming the H rows below row 25 already have some values. Is this the case?
If you use as END the last row with values in column G, you can use Selection.AutoFill.
If you already have values in column H and want to go through them, you can define a dynamic range and loop through it in VBA.
To define a dynamic range: Add a new range, based in this formula (you may need to adapt it according to your needs, obviously)
=OFFSET(Sheet1!$H$25,0,0,COUNTA(Sheet1!$H:$H),1)
And then, in VBA, go through it.
Sub TEST()
Dim oCell As Excel.Range
Dim oRange As Excel.Range
Set oRange = [TestRange]
For Each oCell In oRange
Debug.Print oCell.VALUE
Next oCell
End Sub
In time: To delete an entire row in Excel, you'll use
Sheets(1).Rows(25).EntireRow.Delete
A Do While() Loop sounds like what you might need.
Do While(cells(row,col)<>"")
'Some code to be executed on cell(row,col)
Loop
Or you could do the same thing with for loop
and find the last cell using lastRow=Cells("H24").End(xlDown).Row. (It is the same thing as pressing Ctrl+Down. so if there are empty cells between cell H25 and the end you will need to account for that).
Either way I'd definitely look into using the R1C1 cell reference style for moving through cells instead of the A1 style. You moving through lettered columns is much more difficult than numbered columns. Also you should keep in mind that the "last row" in Excel 2007 is a very high number and looping all the way until the end can take a lot longer than looping until the last important cell.
I hope that's on the right track.