I am making a table in VBA, and as you can see in my sample table here, I have certain merges about every 2 rows of cells made dependent on various cells. However, a part of the table that can be static is column C in the dark gray. I simply want it to do a number count starting at 1 and continuing to the end of my table but skipping the red horizontal lines and leaving them blank. So, red would be 1, orange 2, yellow 3, etc. Here is the code I want to make more efficient. I could type out every number, but that just seems so inefficient.
range("C3:C8").Select
ActiveCell.FormulaR1C1 = "1"
With Selection
.MergeCells = True
.HorizontalAlignment = xlCenterAcrossSelection
.VerticalAlignment = xlBottom
End With
range("C10:C12").Select
ActiveCell.FormulaR1C1 = "2"
With Selection
.MergeCells = True
.HorizontalAlignment = xlCenterAcrossSelection
.VerticalAlignment = xlCenter
End With
range("C9:C10").Select
ActiveCell.FormulaR1C1 = "3"
With Selection
.MergeCells = True
.HorizontalAlignment = xlCenterAcrossSelection
.VerticalAlignment = xlCenter
End With
I would use that there is text in column D.
Sub add_counter()
'Created by Fredrik Östman www.scoc.se
counter = 1
For i = 7 To ActiveSheet.UsedRange.Rows.Count + ActiveSheet.UsedRange.Row
If Cells(i, 4) <> "" Then
Cells(i, 3) = counter
With Range(Cells(i, 3), Cells(i + 1, 3))
.MergeCells = True
.HorizontalAlignment = xlCenterAcrossSelection
.VerticalAlignment = xlBottom
End With
counter = counter + 1
End If
Next i
End Sub
Related
Hi I'm currently using a macro that autoformats tables for me and aligns all cells centrally except for the ones in the first selected column.
I was wondering if there was a way to tweak this so that the 1st selected column is aligned left only if it contains text and not if it contains a number
Here's the code:
Sub Test_align_left()
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Selection.Columns(1).Select
On Error Resume Next
With Selection
.SpecialCells(xlCellTypeConstants, xlTextValues).HorizontalAlignment = xlLeft
.SpecialCells(xlCellTypeFormulas, xlTextValues).HorizontalAlignment = xlLeft
End With
End Sub
Thanks in advance,
Thomas
If you mean left align if text or centred if numeric then here is a way which avoids looping through each cell.
Sub x()
On Error Resume Next
With Columns(1)
.SpecialCells(xlCellTypeConstants, xlTextValues).HorizontalAlignment = xlLeft
.SpecialCells(xlCellTypeConstants, xlNumbers).HorizontalAlignment = xlCenter
.SpecialCells(xlCellTypeFormulas, xlNumbers).HorizontalAlignment = xlCenter
.SpecialCells(xlCellTypeFormulas, xlTextValues).HorizontalAlignment = xlLeft
End With
End Sub
If you just want to leave the first column alone you could do something like:
Sub Test_align_left()
'Test_align_left Macro
With Selection.offset(0,1).resize(,Selection.columns.count-1)
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
End Sub
An agency I am working with just recently upgraded to Windows 10 and also upgraded from Office 2010 to 2016. All machines have the same image This agency exports reports from SSRS into an Excel document. We have an in house macro that automatically edits and formats the report for publication. For some reason when the same excel document with the same report and formatted table is opened on a different computer, the column widths very. The column widths are set via hard coded values in the macro. This affects the presentation of their final publication and, although it is just barely off, it is unacceptable to their clients.
I have explored a few different possibilities. I first looked at the font and its size after the document was opened on the different machine. They are both the same. I then looked to see if resolution may play a role. Although changing the DPI settings appeared to change the column width values, the DPI settings are the same on all the machines. If the macro is run again on the same report the column widths turn out correctly.
I'm really not sure what else to check. Could someone give me some advice or point me in the right direction?
Sub FormatAppDeptLvl()
'Macro to format Long Bill Department Level report
Dim wsSheet As Worksheet
Dim lastRow As Integer
Dim lastCol As Integer
Dim i As Integer, j As Integer, k As Integer, m As Integer, n As Integer, p As Integer, q As Integer
Dim checktotal As String
'Sheets.Add
Application.DisplayAlerts = False
On Error Resume Next
Set wsSheet = Sheets("NewReport")
On Error GoTo 0
If Not wsSheet Is Nothing Then
'Sheet1 exists
Sheets("NewReport").Delete
Sheets.Add().Name = "NewReport"
Else
'Sheet1 does not exist
Sheets.Add().Name = "NewReport"
End If
Sheets("CLMAppropDept").Select
With ActiveSheet
lastRow = .Cells(.Rows.Count, "F").End(xlUp).Row
End With
With ActiveSheet
lastCol = .Cells(lastRow, .Columns.Count).End(xlToLeft).Column
End With
Range(Cells(1, 1), Cells(lastRow, lastCol)).Select
Selection.Copy
'To unHighlight cells
Cells(1, 1).Select
Sheets("NewReport").Select
Range("A1").Select
ActiveSheet.Paste
ActiveSheet.Unprotect
Range(Cells(1, 1), Cells(lastRow, lastCol)).Select
Selection.Locked = False
Selection.FormulaHidden = True
Call ColorTabs
'Calculate last row and column
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
lastCol = ActiveSheet.Cells(lastRow, ActiveSheet.Columns.Count).End(xlToLeft).Column
'Merge Title
Range(Cells(1, 1), Cells(1, lastCol)).Select
Selection.Merge
'Range("B1:G1").Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlLTR
.MergeCells = True
End With
'Table dimensions : Rows Height
ActiveSheet.Rows.RowHeight = 10
Range(Cells(1, 1), Cells(1, lastCol)).RowHeight = 12
Range(Cells(2, 1), Cells(2, lastCol)).RowHeight = 18
Range(Cells(3, 1), Cells(lastRow, 1)).RowHeight = 10
'Table dimensions : Column Width
ActiveSheet.Columns.ColumnWidth = 11.86
Range("A:A").ColumnWidth = 29.075
'Table dimensions : Column Width
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
For k = 2 To lastCol
checkfund = Cells(2, k).Value
If checkfund Like "TOTAL*" Then
Range(Cells(3, k), Cells(lastRow, k)).ColumnWidth = 11 'Total
End If
If checkfund Like "GENERAL*" Then
Range(Cells(3, k), Cells(lastRow, k)).ColumnWidth = 12.071432 'GF
End If
If checkfund Like "CASH*" Then
Range(Cells(3, k), Cells(lastRow, k)).ColumnWidth = 12.0714275 'CF
End If
If checkfund Like "REAPPROPRIATED*" Then
Range(Cells(3, k), Cells(lastRow, k)).ColumnWidth = 12.28422 'RF
End If
If checkfund Like "FEDERAL*" Then
Range(Cells(3, k), Cells(lastRow, k)).ColumnWidth = 12.071425 'FF
End If
If checkfund Like "*FTE" Then
Range(Cells(3, k), Cells(lastRow, k)).ColumnWidth = 7.425 'FTE
End If
Next k
'Justify 1st column Left and Bottom
Range(Cells(4, 1), Cells(lastRow, 1)).Select
With Selection
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlCenter 'Bottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.ShrinkToFit = False
.ReadingOrder = xlLTR
.MergeCells = False
End With
'Justify right columns Rigth and Bottom
Range(Cells(4, 2), Cells(lastRow, lastCol)).Select
With Selection
.HorizontalAlignment = xlRight
.VerticalAlignment = xlCenter 'Bottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.ShrinkToFit = False
.ReadingOrder = xlLTR
.MergeCells = False
End With
'Padding
For j = 4 To lastRow
'MsgBox "Cell Len =" & Len(Cells(j, 1).Value)
If Len(Cells(j, 1).Value) > 41 And Len(Cells(j, 1).Value) <= 72 Then
Range(Cells(j, 1), Cells(j, 1)).Select
Range(Cells(j, 1), Cells(j, 1)).RowHeight = 20 '25
With Selection
.WrapText = True
End With
Range(Cells(j, 2), Cells(j, lastCol)).Select
With Selection
.HorizontalAlignment = xlRight
.VerticalAlignment = xlTop
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlLTR
.MergeCells = False
End With
ElseIf Len(Cells(j, 1).Value) > 72 And Len(Cells(j, 1).Value) <= 108 Then
Range(Cells(j, 1), Cells(j, 1)).Select
Range(Cells(j, 1), Cells(j, 1)).RowHeight = 30 '36
With Selection
.WrapText = True
End With
Range(Cells(j, 2), Cells(j, lastCol)).Select
With Selection
.HorizontalAlignment = xlRight
.VerticalAlignment = xlTop
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlLTR
.MergeCells = False
End With
ElseIf Len(Cells(j, 1).Value) >= 109 Then
Range(Cells(j, 1), Cells(j, 1)).Select
Range(Cells(j, 1), Cells(j, 1)).RowHeight = 40 '47
With Selection
.WrapText = True
End With
Range(Cells(j, 2), Cells(j, lastCol)).Select
With Selection
.HorizontalAlignment = xlRight
.VerticalAlignment = xlTop
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlLTR
.MergeCells = False
End With
End If
Next j
'Merging BREAKDOWN row
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
For i = 3 To lastRow
checktotal = Cells(i, 1).Value
If checktotal Like "BREAKDOWN*" Then
Range(Cells(i, 1), Cells(i, lastCol)).Select
With Selection
.VerticalAlignment = xlCenter
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlLTR
.MergeCells = True
.HorizontalAlignment = xlLeft
.Rows.RowHeight = 15
End With
Selection.Merge
Cells(i, 1).RowHeight = 10
End If
Next i
Cells(lastRow + 2, 1).Select
'Clear the Clipboard
Application.CutCopyMode = False
End Sub
I found the solution. It turns out it was the DPI setting after all. The user of the machine on which we were testing had changed the DPI settings in between the time we had checked the settings and actually tested.
When The DPI settings are changed, Display Settings> Advanced Display Settings> Advanced sizing of text and other items> Set a custom scaling level, the initial widths of excel columns in an excel spreadsheet change. I am not sure if this is a result of upgrading to windows 10, or the upgrade to office '16 (or both). Either way, we just have to make sure this setting is uniform on all machines.
I had a similar issue with column widths being different on different computers, and it turned out that the computer where it looked "wrong" did not have a font installed (Meiryo UI), whereas the computer where I had worked on the file did have this font. Also, the image widths were affected -- any picture I had added from the "right" computer looked too narrow on the other one.
I've been working on creating a dynamic report in MS Excel. I'm working on a legacy VB6 application and I've come across a few issue that I hope ya'll can help me resolve. What I'm doing below, is grabbing data into my recordset g_RS3 - typically this has anywhere from 3 to 20 items, and I use g_RS3 to enter values (headings, and 2 column values under each heading: clients, buyers) into my excel spreadsheet. I'm trying to make an edit to it but I've been struggling with it. This is my code....
Do While Not g_RS3.EOF
With xlSheet.Cells(xlRow, xlCol)
.Value = g_RS3("Label")
.Offset(1, 0).Value = "Clients"
.Offset(1, 1).Value = "Buyers"
With .Offset(1, 0)
.Font.Bold = True
.Borders.Weight = xlThin
End With
With .Offset(1, 1)
.Font.Bold = True
.Borders.Weight = xlThin
End With
With .Resize(1, 2)
.Font.Bold = True
.WrapText = True
.VerticalAlignment = xlCenter
.Merge
.HorizontalAlignment = xlCenter
.Borders.Weight = xlThin
End With
End With
xlCol = xlCol + 2
g_RS3.MoveNext
Loop
I am attaching an image that will show what it looks like. At the end of the recordset I'm trying to add another heading that just says TOTAL and has the 2 columns below it. But I'm having a difficult time doing that.
This is a case where it makes sense to extract a stand-alone piece of functionality from your main code: the header block formatting can go into a separate Sub, so you can call it either from within the recordset loop or for a single set of headings
Main code then becomes
'headers from recordset
Do While Not g_RS3.EOF
DoBlock xlsheet.Cells(xlRow, xlCol), g_RS3("Label"), "Clients", "Buyers"
g_RS3.MoveNext
xlCol = xlCol + 2
Loop
'Extra header
DoBlock xlsheet.Cells(xlRow, xlCol), "Total", "Clients", "Buyers"
Extracted code:
EDIT - tidied up
Sub DoBlock(rng As Range, h1, h2, h3)
With rng
.Value = h1
.WrapText = True
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlCenter
.Offset(1, 0).Value = h2
.Offset(1, 1).Value = h3
With .Resize(2, 2)
.Font.Bold = True
.Borders.Weight = xlThin
End With
.Resize(1, 2).Merge
End With
End Sub
I think just adding one more WITH statement to add the TOTAL cells after your loop would do it. xlCol should already be pointing to the next column based on the last part of the loop (xlCol = xlCol + 2), so I believe this should work.
Do While Not g_RS3.EOF
With xlSheet.Cells(xlRow, xlCol)
.Value = g_RS3("Label")
.Offset(1, 0).Value = "Clients"
.Offset(1, 1).Value = "Buyers"
With .Offset(1, 0)
.Font.Bold = True
.Borders.Weight = xlThin
End With
With .Offset(1, 1)
.Font.Bold = True
.Borders.Weight = xlThin
End With
With .Resize(1, 2)
.Font.Bold = True
.WrapText = True
.VerticalAlignment = xlCenter
.Merge
.HorizontalAlignment = xlCenter
.Borders.Weight = xlThin
End With
End With
xlCol = xlCol + 2
g_RS3.MoveNext
Loop
With xlSheet.Cells(xlRow, xlCol)
.Value = "TOTAL"
.Offset(1, 0).Value = "Clients"
.Offset(1, 1).Value = "Buyers"
With .Offset(1, 0)
.Font.Bold = True
.Borders.Weight = xlThin
End With
With .Offset(1, 1)
.Font.Bold = True
.Borders.Weight = xlThin
End With
With .Resize(1, 2)
.Font.Bold = True
.WrapText = True
.VerticalAlignment = xlCenter
.Merge
.HorizontalAlignment = xlCenter
.Borders.Weight = xlThin
End With
End With
I am facing the problem to proecess a report I got into a useful structured excel model.
My problem is that cells in this report are merged and now I would like to unmerge them to process the information much easier.
I tried to record something using the macro recorder, but I am unsure how to automate it on every cell in the sheet.
I would like to let the output look like that:
This is the part I recorded:
Sub Macro1()
Range("A2:A3").Select
With Selection
.HorizontalAlignment = xlGeneral
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
Selection.UnMerge
Range("A2").Select
Selection.AutoFill Destination:=Range("A2:A3")
Range("A2:A3").Select
End Sub
Any suggestions how to rewrite this macro to do the merging and pasting automatically?
Appreciate your replies!
UPDATE
I tried to use the selection, however, I am currently facing the problem of not knowing how to get next cell:
Sub split()
'
'Dim C As Double
'Dim R As Double
Dim Rng As Range
'select cells
Set Rng = Selection
'C = Rng
'R = 10
For Each cell In Rng
'starts in row 2 and A -> cell 2,1 is the first cell or A2
cell.Select
With Selection
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
Selection.UnMerge
'Cells(R + 1, C) = Cells(R, C)
If cell.Value = "" Then MsgBox ("Finished splitting and copying!"): End
' If C = 7 Then C = 0: R = R + 2
Next cell
End Sub
Sub Macro1()
NbRows = Sheets("Feuil1").UsedRange.Rows.Count - 1
NbCols = 9 ' If it doesn't change
Range("A2:I11").Copy Destination:= _
Range("K2")
Range("K:S").MergeCells = False ' remove merge
For i = 2 To NbRows ' Number of rows
For j = 11 To NbCols + NbCols ' Number of cols
If Cells(i, j) = "" Then
Cells(i, j) = Cells(i - 1, j).Value
End If
Next j
Next i
End Sub
My code copy-paste the datas from the first table to the cell "K2" (as in your example). Then, you remove the merge that will left some blanks. What you want to do is if cells(i , 1) is empty, then you just use the data from above (cells(i-1, 1))
if the data you want to change is on columns a to g and your are starting from row 2 and assuming all of the cell are not empty
try this code:
Sub split()
'
Dim C As Double
Dim R As Double
C = 1
R = 2
For C = 1 To 7
Cells(R, C).Select
With Selection
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
Selection.UnMerge
Cells(R + 1, C) = Cells(R, C)
If Cells(R, C).Value = "" Then MsgBox ("PROJECT ENDED"): End
If C = 7 Then C = 0: R = R + 2
Next C
End Sub
Please save your data before running the macro. You cannot undo.
I have excel sheet prepared as a data entry sheet called “INPUT SHEET”. Data is added in various columns against fixed certain no. of rows of this “INPUT SHEET”.
At the end of each row I have provided one macro button which picks the value from each column and creates another new sheet.
The problem is that I have 100 such columns and I want to avoid editing each macro to work against each column. I want a single macro which identifies column against which the button is pressed and accordingly works on that column only.
Sample macro for COLUMN U is as below: I want a little modification in this sheet so that same code can be applicable to all coulmns.
' Macro1 Macro===ROW U
'
' Create new sheet copying from DATASHEET 1 before last sheet
'
Worksheets("DATASHEET 1").Copy before:=Sheets(Worksheets.Count)
Set wks = ActiveSheet
Sheets("INPUT").Select
Range("U10").Select
Selection.Copy
' Retaining the name of sheet
'
Range("U150").Select
ActiveSheet.Paste
wks.Name = Range("U10").Value
' Copying the notes
'
Worksheets(Range("u10").Value).Activate
Range("D62:BF87").Select
Selection.ClearContents
Range("AY6").Value = "2"
Range("A7:BF7").Select
ActiveCell.FormulaR1C1 = "=INPUT!R[3]C[20]"
Dim i As Integer, j As Integer
j = 61
For i = 63 To 88
Sheets("INPUT").Select
If Cells(i, 21).Value = "YES" Then
j = j + 1
Worksheets(Range("U10").Value).Activate
Range(Cells(j, 4), Cells(j, 58)).Select
With Selection
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlCenter
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
Selection.UnMerge
Sheets("INPUT").Select
Cells(i, 2).Copy
Worksheets(Range("U10").Value).Activate
Cells(j, 4).PasteSpecial Paste:=xlPasteValues
Range(Cells(j, 4), Cells(j, 58)).Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Selection.Merge
With Selection
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlCenter
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
End If
Next i
Rather than having 100 buttons, I would probably work with just one, and move it according to the selected cell. That way each time the cursor moves, the button moves and you could then use the activecell.column method to sum that column.
The code you could use would be something like:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
ActiveSheet.Shapes("Button 1").Left = Cells(40, ActiveCell.Column).Left
End Sub
In the sheet of the workbook you are working on. The button in row 40 will move to the selected column.