Reputation: 9
I am new to Excel VBA. I have made a macro-enabled Excel to record survey responses. Whenever I run the macro, certain cells get copied (from Sheet1) and stored as a row vector in another worksheet (Sheet2).
The problem is that, if Responder1 has some blank cells in his response, then when I record another response (Responder2), then values corresponding to the variable where Responder1 had blanks, are stored in the previous row.
Here is the VBA code
Sub Submit1()
Range("A2:C2").Select #in Sheet1
Selection.Copy
Sheets("Sheet2").Select
Worksheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).PasteSpecial
End Submit1
Now there are two things that I can think of doing:-
Upvotes: 0
Views: 1339
Reputation: 23974
Try the following code:
Sub Submit1()
Dim nextRow As Long
With Worksheets("Sheet2")
'Find the last non-empty cell in the worksheet, and determine its row
'Then add 1 to that, so we are pointing at the next row
nextRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
'Copy values to "nextRow"
Worksheets("Sheet1").Range("A2:C2").Copy .Cells(nextRow, "A")
'Perform other copies as necessary, e.g.
Worksheets("Sheet1").Range("A5:D5").Copy .Cells(nextRow, "D")
Worksheets("Sheet1").Range("X4:Z4").Copy .Cells(nextRow, "H")
End With
End Sub
Regarding your second suggestion: Just don't do it.
Upvotes: 1
Reputation: 5388
Quick answer:
Use Worksheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).PasteSpecial SkipBlanks = False
Reference from MSDN:
SkipBlanks True to have blank cells in the range on the Clipboard not be pasted into the destination range. The default value is False.
However, using Select
is not considered good practice. Consider reading this for more information. For copy-pasting ranges, I cannot recommend more Chip Pearson's page.
Demo:
Sub test()
Dim LastRow As Long Dim arCopy() As Variant
Dim rDest As Range
With Sheet2 ' --> Qualify the ranges
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1 End With
arCopy = Sheet1.Range("A2:K2").Value
Set rDest = Sheet2.Cells(LastRow, "A")
Set rDest = rDest.Resize(1, UBound(arCopy, 2))
rDest.Value = arCopy
End Sub
Sheet1:
The above has the added benefit that you do not need to worry about Blank cells, as they are copied by default.
I hope this helps!
EDIT (addressing comments)
SkipBlanks = False
by default, your PasteSpecial
does not skip blanks. Are you sure your cells are indeed blank and do not appear to be blank? You can make a quick check with the ISBLANK()
function. If SkipBlanks
appears to be working only some times, then there is certainly something different with respect to the cells it is applied to.With ... End With
: This is a shortcut construct that enhances readability. Basically, a block of methods or properties that are under the same object, such as
Sheet1.Range("A1")="Rob"
Sheet1.Copy("A2")
Sheet1.Rows.Count
can be written as
With Sheet1
.Range("A1") = "Rob"
.Copy("A2")
.Rows.Count
End With
This enhances readability
Your second suggestion
can we assign some value for e.g. NULL or 0 to those blank cells, so that the new response can be stored in new row.
In principle, this is possible. However, you should identify which cells are "blank", and we already know that one method that does not skip blanks does not appear to work, so identifying blank cells and substituting them is a bit of a catch 22. In other words, if we knew how to find these "blank" cells so that we assign them NULL or 0, then SkipBlanks
would had taken care of them in a more elegant way (because it is designed to do exactly this).
Upvotes: 0