VBA Copy and paste a range of numbers - range

I'm trying to copy and paste a range, to create a 28 by 28 grid of numbers "rotating" the values so that each time the range is pasted into the next column, the range is moves down by one row and the last value "overflows" back to the top of the next row, I've got this far but am stumped on the overflow part (i' relative newbie to VBA)
Sub Test()
Dim oRange As Range
Set oRange = ActiveSheet.Range("A1:A28")
Dim i As Integer
For i = 1 To 28
oRange.Copy
oRange.Offset(i, i).PasteSpecial xlPasteAll
Next i
End Sub
Also I need to copy and paste values and formatting of the cells
Hope you guys can help
Thanks
Dan

Sub Test()
Dim oRange As Range
Dim startColumn As String
Dim rangeStart As Integer
Dim rangeEnd As Integer
Dim cellCount As Integer
Dim i As Integer
startColumn = "A"
rangeStart = 1
rangeEnd = 28
cellCount = rangeEnd - rangeStart + 1
For i = 1 To cellCount - 1
Set oRange = ActiveSheet.Range(startColumn & rangeStart & _
":" & startColumn & (rangeEnd - i))
oRange.Copy
oRange.Offset(i, i).PasteSpecial xlPasteAll
Set oRange = ActiveSheet.Range(startColumn & (rangeEnd - i + 1) & _
":" & startColumn & rangeEnd)
oRange.Copy
oRange.Offset((-1 * cellCount) + i, i).PasteSpecial xlPasteAll
Next i
End Sub
EDIT:
to insert a blanck row at index 'i':
Rows(i & ":" & i).Select
Selection.Insert Shift:=xlDown
to insert 5 rows at the top of the worksheet insert a row 5 times at index 1:
For i = 1 To 5
Rows("1:1").Select
Selection.Insert Shift:=xlDown
Next

Related

How to copy data into cells, make a table and add more data to it

UI looks like:
Account:Wessex bank plc
Income: 200€
Costs:
Date: 28.02.2021
Output should be a list below in the cells:
Date: | Account: | Income: | Costs: |
28.02.2021 | Wessex Bank plc | 200€ |
28.02.2021 | Food | - | 175€ |
Hint: I would like to have a list of 5-7 bookings and when
making a new booking the latest booking is going to be at the top position and the first booking in the last row, like when the table starts at row 13 and I make 5 bookings with different accounts, the first booking will be at 17 in the end.
this is copying the content in the table
Sub MyBuchenMakro
Dim currDoc As Object
Dim currSheet As Object
Dim curr Cell As Object
Dim destCell As Object
Dim oDate As Date
Dim einnahmen As Currency
Dim ausgaben As Currency
currDoc = ThisComponent
currSheet = currDoc.sheets(0)
currCell = currSheet.getCellByPosition(1, 5)
destCell = currSheet.getCellByPosition(1, 12)
destCell.String = currCell.String
currCell = currSheet.getCellByPosition(1, 6)
destCell = currSheet.getCellByPosition(2, 12)
destCell.setValue(CCur(currCell.getValue()))
currCell = currSheet.getCellByPosition(1, 7)
destCell = currSheet.getCellByPosition(3, 12)
destCell.setValue(CCur(currCell.getValue()))
currCell = currSheet.getCellByPosition(1, 8)
destCell = currSheet.getCellByPosition(0, 12)
destCell.setValue(CDate(currCell.getValue()))
For i = 160 To 13 Step 1
destCell = currSheet.getCellByPosition(0, i)
If destCell == "" Then
GoTo Continue
End if
destCell = currSheet.getCellByPosition(0,i+1)
destCell.setValue(CDate(currCell.getValue()))
currCell = currSheet.getCellByPosition(1,i)
destCell = currSheet.getCellByPosition(1,i+1)
destCell.String = currCell.String
currCell = currSheet.getCellByPosition(2,i)
destCell = currSheet.getCellByPosition(2,i+1)
destCell.setValue(CCur(currCell.getValue()))
currCell = currSheet.getCellByPosition(3,i)
destCell = currSheet.getCellByPosition(3,i+1)
destCell.setValue(CCur(currCell.getValue()))
Next i
End Sub
[1]: https://i.stack.imgur.com/Mw7pJ.png
In fact, it is written a little shorter:
Option Explicit
Sub BuchenMacro
Dim oCurrentController As Variant ' get Activesheet and select first cell of form
Dim oSheet As Variant ' Activesheet
Dim oSourceRange As Variant ' Range B6:B9 - fields of input form
Dim oDataArray As Variant ' Data from input form
oCurrentController = ThisComponent.getCurrentController()
oSheet = oCurrentController.getActiveSheet()
Rem Range with data
oSourceRange = oSheet.getCellRangeByName("B6:B9")
Rem Data from this range as "array of arrays"
oDataArray = oSourceRange.getDataArray()
Rem To prevent insert empty row - validate source cells:
Rem If 3 first cells are empty then stop:
If Trim(oDataArray(0)(0))+Trim(oDataArray(1)(0))+Trim(oDataArray(2)(0)) = "" Then Exit Sub
Rem "Transpose" source data to single row:
oDataArray = Array(Array(oDataArray(3)(0), oDataArray(0)(0), oDataArray(1)(0), oDataArray(2)(0)))
Rem Insert new row after header and shift all other rows down:
oSheet.getRows().insertByIndex(12, 1)
Rem Paste data from form to this new row
oSheet.getCellRangeByPosition(0, 12, 3, 12).setDataArray(oDataArray)
Rem Clear input cells to prevent duplicates
Rem (Only the data is cleared, the formulas remain in place.
Rem Put in cell B9 the formula =TEXT(TODAY();"DD.MM.YYYY")
Rem and it will always show the current date)
oSourceRange.clearContents(7)
Rem Select first cell
oCurrentController.Select(oSheet.getCellByPosition(1,5))
Rem Deselect cell
oCurrentController.Select(ThisComponent.createInstance("com.sun.star.sheet.SheetCellRanges"))
End Sub

copy column to another different layout worksheet

I wish to copy data from Concur into my destination worksheet - Upload to Sun:
From Concur column J into UploadtoSun column D
From Concur column P into UploadtoSun column J
etc etc
My error message was the last sentence - Application defined or object defined error.
I'm not too sure how to write the last sentence. Can anyone assist ?
Dim ConcurLastRow As Long
Set Concur = ThisWorkbook.Worksheets("Concur")
Set UploadtoSun = ThisWorkbook.Worksheets("UploadtoSun")
Dim ConcurRngF As Range
Dim ConcurRngJ As Range
Dim ConcurRngK As Range
Dim ConcurRngO As Range
Dim ConcurRngP As Range
Dim UploadtoSunRngD As Range
Dim UploadtoSunRngF As Range
Dim UploadtoSunRngJ As Range
Dim UploadtoSunRngK As Range
Dim UploadtoSunRngL As Range
ConcurLastRow = Concur.Cells(Rows.Count, 1).End(xlUp).Row
UploadtoSunLastRow = Worksheets("UploadtoSun").Cells(Rows.Count, 4).End(xlUp).Offset(1, 0).Row
Set ConcurRngF = Concur.Range("F11:G" & ConcurLastRow)
Set ConcurRngJ = Concur.Range("J11:K" & ConcurLastRow)
Set ConcurRngK = Concur.Range("K11:L" & ConcurLastRow)
Set ConcurRngO = Concur.Range("O11:P" & ConcurLastRow)
Set ConcurRngP = Concur.Range("P11:Q" & ConcurLastRow)
Set UploadtoSunRngD = UploadtoSun.Range("D2:E" & UploadtoSunLastRow)
Set UploadtoSunRngF = UploadtoSun.Range("F2:G" & UploadtoSunLastRow)
Set UploadtoSunRngJ = UploadtoSun.Range("J2:K" & UploadtoSunLastRow)
Set UploadtoSunRngK = UploadtoSun.Range("K2:L" & UploadtoSunLastRow)
Set UploadtoSunRngL = UploadtoSun.Range("L2:M" & UploadtoSunLastRow)
Worksheets("UploadtoSun").Range("UploadtoSunRngD").Copy Worksheets("Concur").Range("ConcurRngJ").Value
you could do something like this
Sub Copydata()
Dim lastRow As Long
lastRow = Worksheets("Concur").Range("J:Z").Find("*", , , , xlByRows, xlPrevious).Row
'copy range
Worksheets("Concur").Range("J1:" & "J" & lastRow).Copy Destination:=Worksheets("UploadtoSun").Range("D1")
'copy entire column
Worksheets("Concur").Range("J:J").Copy Destination:=Worksheets("UploadtoSun").Range("K:K")
End Sub
how to get the last row Excel VBA - selecting range to last completely blank row

VBA Excel make array of sequential numbers

I am working in VBA for Excel at the moment but am really only versed in Matlab. It's important for my work to stay in the memory of vba (not on the worksheets of excel) for time purposes.
What I need to do is make an array of sequential integers, say 4000 through 5000.
In matlab this is really easy, I would just do... i = 4000:5000, or i=4000:1:5000. With the 1 in the second case being my 'step.'
I was wondering what is the best way to achieve this result in vba?
Thanks
Without looping - Just seen Rory's same answer above after posting
Sub MakeArray()
Dim x As Long, y As Long, arr As Variant
x = 4000: y = 5000
arr = Evaluate("Row(" & x & ":" & y & ")")
'Show result
Sheets(1).Range("A1").Resize(y - x + 1) = arr
End Sub
The following is an example of creating and then displaying a set of sequential numbers:
Sub seqnum()
Dim firstnum As Long, secnum As Long
firstnum = 7
secnum = 23
ReDim ary(1 To secnum - firstnum + 1) As Long
For i = 1 To UBound(ary)
ary(i) = firstnum + (i - 1)
Next i
msg = ""
For i = 1 To UBound(ary)
msg = msg & i & vbTab & ary(i) & vbCrLf
Next i
MsgBox msg
End Sub
I Us "Fill" - "Series":
Write in first cell number ex. 400 and in the "Series" window insert increment step and in "Stop Value" last value. ex. 420
Or with Macro
Range("I1").Select
ActiveCell.FormulaR1C1 = "4000"
Range("I1").Select
Selection.DataSeries Rowcol:=xlColumns, Type:=xlLinear, Date:=xlDay, _
Step:=1, Stop:=4020, Trend:=False

Align series by value in DevExpress XtraCharts

I have a DevExpress XtraChart object with several series, all of type: line.
I have a requirement from a client to align the series by the max value of each series. This is without regard to the attached axis, has anyone done this before?
Although I was interested in displaying this on the chart element, the 'work' was done on the underlying DataSet.
I was able to achieve this by looping through the series collection, deriving the max value of the first series, through a SQL query, and then each subsequent series, and noting the difference, and then adding or subtracting the difference at the DataSet level.
Here's the code:
Private Sub cbAlignPeaks_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbAlignPeaks.CheckedChanged
Dim dt As DataTable = chart.DataSource
Dim Row() As Data.DataRow
Dim s As Series = Nothing
Dim dtr As DataTableReader = Nothing
Dim maxTimeGet, maxTimeSet, diff As Decimal
Me.Cursor = Cursors.WaitCursor
If cbAlignPeaksPre.Checked Then
For i As Integer = 0 To chartPreTim.Series.Count - 1
s = chartPreTim.Series(i)
If _offsets.Count = chartPreTim.Series.Count - 1 Then
If i > 0 Then
diff = _offsets(s.DataFilters(0).Value)
Row = dt.Select("BORING_NAME = '" & s.Name & "'")
For k As Integer = 0 To Row.Count - 1
Row(k)("TIME_SEC") = Row(k)("TIME_SEC") + diff
Next
End If
Else
If i = 0 Then 'get adjustment info
dtr = getDetectorMax(s.DataFilters(0).Value, cbDetectors.Text, timType.PRE) ' <-- getDetectorMax runs a SQL query returning the max value
If dtr.Read Then
maxTimeGet = dtr("TIME_SEC")
End If
Else 'set adjustment info
dtr = Nothing
dtr = getDetectorMax(s.DataFilters(0).Value, cbDetectors.Text, timType.PRE)
If dtr.Read Then
maxTimeSet = dtr("TIME_SEC")
End If
If maxTimeGet > maxTimeSet Then
diff = maxTimeGet - maxTimeSet
_offsets.Add(s.DataFilters(0).Value, diff)
Row = dt.Select("BORING_NAME = '" & s.DataFilters(0).Value & "'")
For k As Integer = 0 To Row.Count - 1
Row(k)("TIME_SEC") = Row(k)("TIME_SEC") + diff
Next
Else
diff = maxTimeSet - maxTimeGet
_offsets.Add(s.DataFilters(0).Value, diff * -1)
Row = dt.Select("BORING_NAME = '" & s.DataFilters(0).Value & "'")
For k As Integer = 0 To Row.Count - 1
Row(k)("TIME_SEC") = Row(k)("TIME_SEC") - diff
Next
End If
End If
End If
Next
Else
For i As Integer = 1 To chartPreTim.Series.Count - 1 ' We skip item 0 as that's the baseline
s = chartPreTim.Series(i)
diff = _offsets(s.DataFilters(0).Value)
Row = dt.Select("BORING_NAME = '" & s.DataFilters(0).Value & "'")
For k As Integer = 0 To Row.Count - 1
Row(k)("TIME_SEC") = Row(k)("TIME_SEC") - diff
Next
Next
End If
chartPreTim.RefreshData()
chartPreTim.Refresh()
Me.Cursor = Cursors.Default
End Sub

Excel VBA Listbox - Only Format non blanks as Dates

This one has me stumped. I am populating a Listbox with a range and then formatting column 4 as d/mm/yyyy. This works fine if all cells in column 4 have a date. As some cells that are populated into the Listbox are in fact blank the sub crashes when it hits these cells. I have tried various if and else statements to skip the activecell if blank with no luck.
Grateful for any assistance.
Alex V
Sub populate_listbox_1()
Dim I As Long
Dim I2 As Long
Dim list_count As Long
Dim MyData As Range
Dim r As Long
With edit_report_input.compliments_listbox
.ColumnCount = 17
.ColumnWidths = "70;300;75;90;80;80;100;0;0;0;0;0;0;0;0;20;0"
.RowSource = ""
Set MyData = ActiveSheet.Range("A4:Q498") 'Adjust the range accordingly
.List = MyData.Cells.Value
For r = .ListCount - 1 To 0 Step -1
If .List(r, 1) = "" Then
.RemoveItem r
End If
Next r
End With
For I = 0 To edit_report_input.compliments_listbox.ListCount - 1
edit_report_input.compliments_listbox.List(I, 4) = Format(DateValue(edit_report_input.compliments_listbox.List(I, 4)), "d/mm/yyyy")
Next I
date_rec_compliment = Format(date_rec_compliment, "d/mm/yyyy")
End Sub
you can always check before changing the format. See if below snippet helps
For I = 0 To edit_report_input.compliments_listbox.ListCount - 1
if edit_report_input.compliments_listbox.List(I, 4) <> "" Then
edit_report_input.compliments_listbox.List(I, 4) = Format(DateValue(edit_report_input.compliments_listbox.List(I, 4)), "d/mm/yyyy")
End If
Next I