Range in Excel VBA - vba

I have written this code to merge a few lines in each column, from column C to AZ.
For some reason the range does not match the one I was expecting, in this case the code merges the cells C8:C10 then D8:D12, E8:E12, and so on. lines = 2 in this example.
I don't understand why aren't the ranges matching if lines value is not changing inside the for.
Thanks!
For columns = 0 To 49
Range(Range("C8").Offset(0, columns), Range("C8").Offset((lines), columns)).Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = False
.Orientation = 90
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
next comlumns

Columns is a reserved word. And you said that this code did run?
If I change that to a valid variable then the code runs. The problem is the way you are using Offset
?[C8].offset(2).address after the way you merge will give you $C$12
Also avoid the use of .Select INTERESTING READ And not to mention fully qualify your objects. For example your range and cell objects are not fully qualified and may give you error.
I think, this is what you are trying to achieve?
Sub Sample()
Dim ws As Worksheet
Dim rng As Range
Dim i As Long, rw As Long
Set ws = ThisWorkbook.Sheets("Sheet1")
rw = 2
With ws
For i = 3 To 52
Set rng = .Range(.Cells(8, i), .Cells(8 + rw, i))
With rng
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = False
.Orientation = 90
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
Next i
End With
End Sub

Related

VBA Macro that works IF a cell contains text but not if it contains a number

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

Perform formatting on several not adjacent COLUMNS in excel VBA?

With my code I want 2 perform formatting over several not adjacent COLUMNS, and I want to make it elegantly in code. Just as it's supposed to be by the book. I'm learning, so I want to learn the right way.
this is how my task looks like:
I've read this.
I mean... is there really no way to enumerate column letters in COLUMNS method? no way to do this?
So do I need to use RANGE object to preform my task? Is it correct?
How do I use UNION method in conjunction with "With... End With"
This is my case I guess.
Please explain more in detail than only 1,5 line answer please.
I will need to do the same things with Columns: B, C, G, H.
They will be formatted .NumberFormat = "#,##0.00"
Option Explicit
Dim VBA As Worksheet
Dim Filter As String
Dim Stock As Variant
Dim Index As Variant
Dim Portfolio As Variant
' Dim Date as Range
Sub Columns_Formatting()
Set VBA = Workbooks("kgh pricing model thursday.xlsm").Worksheets("VBA")
Filter = "Pliki CSV, *.csv," & "Pliki TXT, *.txt," & "All Files, *.*"
' Stock = Application.GetOpenFilename(fileFilter:=Filter, FilterIndex:=1, Title:="Choose file with a stock prices")
' Index = Application.GetOpenFilename(fileFilter:=Filter, FilterIndex:=1, Title:="Choose file with an index values")
' If Stock = False Or Index = False Then MsgBox "Canceled": Exit Sub
With VBA.Columns("A:A,F:F") ' here is the error = type mismath
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = True
.NumberFormat = "yyyy-mm-dd;#"
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
.ColumnWidth = 12
End With
With VBA.Columns("A;F")
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = True
.NumberFormat = "General"
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
.ColumnWidth = 12
End With
With VBA.Range("E2:E" & Rows.Count)
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlCenter
.WrapText = True
.NumberFormat = "#,##0"
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
.ColumnWidth = 10
End With
Use a Range object with full column references. You might also want to cut down the full column references to the Worksheet.UsedRange property with the Intersect method.
With VBA
With Intersect(.UsedRange, .Range("A:A,F:F"))
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = True
.NumberFormat = "yyyy-mm-dd;#"
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
.ColumnWidth = 12
End With
End With

How to range.find a value in a merged cell

I have a worksheet with merged cells (e.g. B2:C3 with value "myValue"). If I try to search for a value which is in a merged cell with
r = ThisWorkbook.ActiveWorksheets.Range("$A:$D").Find("myValue")
Debug.Print r.Address
I only get the address of other single cells with similar values but not of the merged cell.
How can I do this with VBA? If I use the manual search function of Excel it finds the value in no time.
Best regards,
Harry
EDIT: When I use the code from Gary I get a runtime error 91. The variable r is Nothing.
Cleaning up a few things:
Sub MAIN()
Dim r As Range
Call Setup
Set r = ThisWorkbook.ActiveSheet.Range("$A:$D").Find("myValue")
Debug.Print r.Address
End Sub
Sub Setup()
Dim rng As Range
Set rng = Range("B2:C3")
With rng
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
End With
rng.Value = "MyValue"
End Sub
Will get you the upper left-hand corner of the merged area:
you should use MergeArea for such cases:
Sub test()
Dim r As Range
Set r = ThisWorkbook.ActiveSheet.[A:D].Find("myValue")
Debug.Print r.MergeArea.Address
End Sub

Unmerge and paste cells down with vba

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.

Macros applicable on one column can be applicable to all column in excel VB

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.