I am currently trying to write some VBA code which will fill out all cells between two cells with the value of the two cells.
Here is what I have :
And I would like the code to fill out all cells in between like this:
So, as you can see I would like all the cells in between to be filled out with the same value as the two corner cells.
Any help is very much appreciated! Thanks in advance.
you could use SpecialCells() method of Range object:
Sub main()
Dim cell As Range
For Each cell In Intersect(Columns(1), ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).EntireRow)
With cell.EntireRow.SpecialCells(xlCellTypeConstants)
Range(.Areas(1), .Areas(2)).Value = .Areas(1).Value
End With
Next
End Sub
Place this in a new module and run test_DTodor:
Option Explicit
Sub test_DTodor()
Dim wS As Worksheet
Dim LastRow As Double
Dim LastCol As Double
Dim i As Double
Dim j As Double
Dim k As Double
Dim RowVal As String
Set wS = ThisWorkbook.Sheets("Sheet1")
LastRow = LastRow_1(wS)
LastCol = LastCol_1(wS)
For i = 1 To LastRow
For j = 1 To LastCol
With wS
If .Cells(i, j) <> vbNullString Then
'1st value of the row found
RowVal = .Cells(i, j).Value
k = 1
'Fill until next value of that row
Do While j + k <= LastCol And .Cells(i, j + k) = vbNullString
.Cells(i, j + k).Value = RowVal
k = k + 1
Loop
'Go to next row
Exit For
Else
End If
End With 'wS
Next j
Next i
End Sub
Public Function LastCol_1(wS As Worksheet) As Double
With wS
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
LastCol_1 = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Else
LastCol_1 = 1
End If
End With
End Function
Public Function LastRow_1(wS As Worksheet) As Double
With wS
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
LastRow_1 = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
LastRow_1 = 1
End If
End With
End Function
Related
Struggling with this counter...
I am going through multiple pages of info and trying to count the number of overdue tasks then inserting this info into a statistics page.
Sub data_input_overdue()
Dim rw As Long
Dim Counter As Long
Dim col As Long
col = CountMyCols("Stats")
Worksheets("Stats").Cells(2, col + 1).Value = "Overdue"
Counter = 0
For Each sht In ThisWorkbook.Sheets
For i = 2 To CountMyRows(sht.Name)
c_date = Range("E" & i)
dueDate = CDate(c_date)
If dueDate < Date And sht.Range("I" & i).Value = "No" Then
Counter = Counter + CLng(1)
Worksheets("Stats").Cells(i, col + 1).Value = Counter
End If
Next i
Next sht
End Sub
Public Function CountMyRows(SName As String) As Long
On Error Resume Next
With ThisWorkbook.Worksheets(SName)
CountMyRows = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Its not counting and going into the right places in the table as well. I want it to go into a column starting on the 3rd row.
In the multiple sheets there is a mixture of completed and uncompleted tasks
I think this is what you are trying to do, but I'm not sure how you will identify each total with the applicable sheet.
Sub data_input_overdue()
Dim c_date
Dim dueDate As Date
Dim i As Long
Dim Counter As Long
Dim cntSheet As Long
Dim col As Long
col = CountMyCols("Stats")
Worksheets("Stats").Cells(2, col + 1).Value = "Overdue"
cntSheet = 0
For Each sht In ThisWorkbook.Worksheets
If sht.Name <> "Stats" Then ' Don't process the Stats sheet
cntSheet = cntSheet + 1
'Reset counter at the start of each sheet
Counter = 0
For i = 2 To CountMyRows(sht.Name)
c_date = sht.Range("E" & i)
dueDate = CDate(c_date)
If dueDate < Date And sht.Range("I" & i).Value = "No" Then
Counter = Counter + 1
End If
Next i
'Update Stats sheet after finished counting
Worksheets("Stats").Cells(2 + cntSheet, col + 1).Value = Counter
End If
Next sht
End Sub
Public Function CountMyRows(SName As String) As Long
On Error Resume Next
With ThisWorkbook.Worksheets(SName)
CountMyRows = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
End With
End Sub
Public Function CountMyCols(SName As String) As Long
On Error Resume Next
With ThisWorkbook.Worksheets(SName)
CountMyCols = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
End With
End Sub
If I was doing this, I would probably put the sheet names in column A and the totals in column B, or start with the sheet names in column A, and then use that sheet name to decide which sheet to process when calculating the total to put on that row (rather than just looping through all the sheets in tab order).
I have an issue with the REPLACE function of VBA.
For example, whem I'm in a sheet and use CTRL + H to replace all the "." to ",", it works good.
But when I'm trying to do it with a macro I have an issue with the values > than 1
0.8 ---> 0,8
0.9 ---> 0,9
1.09978063783 ---> 109978063783
Here is the code :
Rows("10:10").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Replace What:=".", Replacement:=",", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False, MatchByte:=False
Would this do the trick for you?
Sub Test()
Dim i As Integer, rng As Range, cell As Range
For i = 10 To 1000
Set rng = Rows(i)
rng.Replace What:=".", Replacement:=",", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False, MatchByte:=False
Next i
End Sub
Try this code:
Sub DotsToCommas()
Dim Txt As String, Col As Long
For Col = 1 To ActiveSheet.Columns.Count
Txt = CStr(ActiveSheet.Cells(10, Col).Value)
If Txt = "" Then
Exit Sub
End If
Txt = Replace(Txt, ".", ",")
ActiveSheet.Cells(10, Col).Value = Txt
Next
End Sub
It will take a bit more time, as it does a loop through all cells until it finds a empty one.
This should do it:
Sub replaceDecimalPoint()
Dim lastRowNum As Long
Dim lastColNum As Long
Dim startRow As Long
Dim tempVal As String
lastRowNum = Cells(Rows.Count, 1).End(xlUp).Row
lastColNum = Cells(10, Columns.Count).End(xlToLeft).Column
startRow = 10 'Change this if row start number is required to be changed from 10
Dim rangeArray As Variant
rangeArray = Range(Cells(startRow, 1), Cells(lastRowNum, lastColNum)).Value 'Assuming to start at row 10 as you have used Row 10 (And Column A) - If NOT, Change startRow
For r = startRow To lastRowNum 'Assuming to start at row 10 as you have used Row 10 - If NOT, Change startRow
For c = 1 To lastColNum
tempVal = rangeArray(r - (startRow - 1), c)
If CDbl(tempVal) > 1 Then
tempVal = CStr((tempVal * (10 ^ (Len(tempVal) - 1))))
End If
rangeArray(r - (startRow - 1), c) = Replace(CStr(tempVal), ".", ",")
Next c
Next r
Range(Cells(startRow, 1), Cells(lastRowNum, lastColNum)).Value = rangeArray
End Sub
some time ago I posted a similar question here and got a great answer. But now I would need a slightly altered code but I am not able to change it up.
In an Excel sheet I have cells which have values but all cells between those two are empty. I want Excel to fill the empty cells between them with the values of a third cell. To visualise:
That's what it looks like
Now I want the macro to fill out all the empty cells with the value of the corresponding J cell. So it would look like this:
From the previous thread I used this code:
Sub main()
Dim cell As Range
For Each cell In Intersect(Columns(1), ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).EntireRow)
With cell.EntireRow.SpecialCells(xlCellTypeConstants)
Range(.Areas(1), .Areas(2)).Value = .Areas(1).Value
End With
Next
End Sub
Is it possible to change up the existing code? Or maybe the other code from my previous, linked question? I looked into both but I myself unfortunately wasn't able.
Any help is appreciated. Thanks in advance.
Use the code from the your other question but change rowval to look at column J
Option Explicit
Sub test_DTodor()
Dim wS As Worksheet
Dim LastRow As Double
Dim LastCol As Double
Dim i As Double
Dim j As Double
Dim k As Double
Dim RowVal As String
Set wS = ThisWorkbook.Sheets("Sheet1")
LastRow = LastRow_1(wS)
LastCol = LastCol_1(wS)
For i = 1 To LastRow
For j = 1 To LastCol
With wS
If .Cells(i, j) <> vbNullString Then
'1st value of the row found
RowVal = .Cells(i, 10).Value --This is all I changed
k = 1
'Fill until next value of that row
Do While j + k <= LastCol And .Cells(i, j + k) = vbNullString
.Cells(i, j + k).Value = RowVal
k = k + 1
Loop
'Go to next row
Exit For
Else
End If
End With 'wS
Next j
Next i
End Sub
Public Function LastCol_1(wS As Worksheet) As Double
With wS
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
LastCol_1 = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Else
LastCol_1 = 1
End If
End With
End Function
Public Function LastRow_1(wS As Worksheet) As Double
With wS
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
LastRow_1 = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
LastRow_1 = 1
End If
End With
End Function
Answer with modifying previous code
Sub main()
Dim cell As Range
For Each cell In Intersect(Columns(1), ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).EntireRow)
With cell.EntireRow.SpecialCells(xlCellTypeConstants)
Range(.Areas(1).Offset(, 1), .Areas(2).Offset(, -1)).Value = Cells(.Areas(1).Row, "J").Value
End With
Next
End Sub
Assuming you have three values in each row and they are not consecutive, a small change to your original code should suffice.
Sub main()
Dim cell As Range
For Each cell In Intersect(Columns(1), ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).EntireRow)
With cell.EntireRow.SpecialCells(xlCellTypeConstants)
Range(.Areas(1).Offset(, 1), .Areas(2).Offset(, -1)).Value = .Areas(3).Value
End With
Next
End Sub
This will do exactly what you want in three lines
Sub FillBlanks()
Dim c
For Each c In ActiveSheet.UsedRange.Columns("J").SpecialCells(xlCellTypeConstants)
Range(c.Offset(0, c.End(xlToLeft).Column - c.Column), c.Offset(0, -c.Column + 1)).SpecialCells(xlCellTypeBlanks).Value2 = c.Value2
Next c
End Sub
I have VBA code written up to find and replace question marks in all worksheets in a workbook. However it is not working, can anyone help me out to see where did i go wrong?
Sub ReplaceQM()
Dim lRow As Long
Dim lCol As Long
totalSheet = ThisWorkbook.Sheets.Count
MsgBox totalSheet
For x = 1 To totalSheet
lRow = ThisWorkbook.Sheets(x).Cells(Rows.Count, 1).End(xlUp).Row
lCol = ThisWorkbook.Sheets(x).Cells(1, Columns.Count).End(xlToLeft).Column
For Z = 1 To lRow
For i = 1 To lCol
getPos = InStr(1, ThisWorkbook.Sheets(x).Cells(Z, i).Value, "~?")
If getPos > 0 Then
ThisWorkbook.Sheets(x).Cells(Z, i).Value = Replace(ThisWorkbook.Sheets(x).Cells(Z, i).Value, "~?", " ")
End If
Next i
Next Z
Next x
End Sub
You're better off using Excel's in-range replace function:
For Each ws In ThisWorkbook
ws.UsedRange.Cells.Replace what:="~?", Replacement:=" ", LookAt:=False, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Next ws
My query is if I insert row using a button, it should also add serial numbers to the rows like 1,2,3 etc...
I have the below code here in Sheet1 of the worksheet for adding the serial numbers when I add rows
Private Sub Worksheet_Change1(ByVal Target As Range)
Dim StartNum As Integer
Dim FirstCell As Integer
Dim LastCell As Integer
StartNum = 2
FirstCell = 3
LastCell = 17
Application.EnableEvents = False
Do While FirstCell <= LastCell
Range("B" & FirstCell).Value = StartNum
FirstCell = FirstCell + 1
StartNum = StartNum + 1
Loop
Range("B" & LastCell + 1).Value = ""
Application.EnableEvents = True
End Sub
The below code is written in module1 to insert rows with formula of A1 copied to new rows
Sub Macro2()
Rows("2:2").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Range("B1:D1").Select
Selection.AutoFill Destination:=Range("B1:D2"), Type:=xlFillDefault
Range("B1:D2").Select
End Sub
Now my Question is how to call the private sub from the Module Macro2 code while inserting rows
Any suggestions, waiting for your replies at the earliest.
Like I mentioned you do not need the Worksheet_Change code for this. Paste the below code in a module and try it..
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long
'~~> Set this to the relevant sheet
Set ws = Sheets("Sheet1")
With ws
'~~> Insert at row 2
.Rows(2).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
'~~> Autofill B1:D1 to C1:D2
.Range("B1:D1").AutoFill Destination:=.Range("B1:D2"), Type:=xlFillDefault
'~~> Find the last row
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
'~~> Renumber the cells in Col B
For i = 1 To lRow
.Range("B" & i).Value = i
Next i
End With
End Sub
FOLLOWUP
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long, j As Double
'~~> Set this to the relevant sheet
Set ws = Sheets("Sheet1")
With ws
'~~> Insert at row 2
.Rows(2).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
'~~> Autofill B1:D1 to C1:D2
.Range("B1:D1").AutoFill Destination:=.Range("B1:D2"), Type:=xlFillDefault
'~~> Find the last row
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
'~~> Renumber the cells in Col B 1,1.1,1.2,1.3 etc
j = 1
For i = 1 To lRow
.Range("B" & i).Value = j
j = j + 0.1
Next i
End With
End Sub