I'm having problems making copy/pasting clean. Currently I have this:
If distanceValue <= distanceParameter Then
sh2.Rows(i).Copy _
sh3.Rows(i).Offset(0, 1)
End If
sh2 and sh3 are properly defined and it's inside a for loop; that's not the problem. Range seems messy to use, as I would have to define a lastcolumn variable, etc. Is there anyway to do this with .Rows?
The goal is to copy a row if it meets the condition to another sheet but leaving column A blank. Any feedback on clean solutions (I know this one is wrong) would be greatly appreciated.
Your copy range (if you copy the entire row) will be larger then your paste range if you offset by a column. You can't paste 16384 columns into 16383, not enough room.
If you do not wish to use the range function, you will have to copy the entire rows then add a column to the front.
Or you could add the column to the source data before the copy paste, removing the columns when finished if needed.
Sub Sample()
Dim sh2 As Worksheet, sh3 As Worksheet
Set sh2 = Worksheets("Sheet1")
Set sh3 = Worksheets("Sheet2")
If distanceValue <= distanceParameter Then
sh2.Rows(i).Copy _
sh3.Rows(i)
End If
sh3.Columns("A").insert
End Sub
OR
Sub Sample()
Dim sh2 As Worksheet, sh3 As Worksheet
Set sh2 = Worksheets("Sheet1")
Set sh3 = Worksheets("Sheet2")
sh2.Columns("A").insert
If distanceValue <= distanceParameter Then
sh2.Rows(i).Copy _
sh3.Rows(i)
End If
'The next line is to return the source data back to the original format remove if not needed
sh2.Columns("A").Delete
End Sub
Your last option and most dynamic would be to work with a listobject/DataTable instead of an excel range. IF POSSIBLE.
If you have a Table already Then you could simply use :
Sub Sample()
Dim sh2 As Worksheet, sh3 As Worksheet
Dim rngCurrentRow As Range
Set sh2 = Worksheets("Sheet1")
Set sh3 = Worksheets("Sheet2")
Set rngCurrentRow = sh2.ListObjects("YourTableNameHere").ListRows(i).Range
If distanceValue <= distanceParameter Then
rngCurrentRow.Copy _
sh3.Cells(i, 2)
End If
End Sub
Making a Range into a table is Very Easy, If your data does not contain blanks its as easy as clicking on the first cell in your Range and Pressing Ctrl+L This will then select your range, If you need to increase the size of your range because it does contain spaces then simple change the input box to select all your Data.
Don't forget if you have heade3rs to check the check box
NOTE: If you are unsure of your Table name simply click on the table then on the ribbon a new tab will pop up and the end called Table Tools/Design. On that tab the left most area contains your table name, You can change this to anything you'd like.
Related
I have a table in Sheet 2 with a name "MyTable". Number of rows of that table changes each time depending on the data. I would like to clear the contents of the table and resize it using a macro so that it has only two rows- a title row, and an empty row.
Table title row is from B5 until K5.
I tried the below code, it clears the table contents and resizes, however, does not resize as desired. It resizes, without clearing the table borders in column C.
Any help is really appreciated.
Sub Table_Resize()
Dim rng as Range
Sheet2.Select
Range("MyTable").ClearContents
Set rng = Range("MyTable[#All]").Resize(2, 10)
Sheet2.ListObjects("MyTable").Resize rng
End Sub
I think that what you are trying to do is to delete the all rows.
Sub Table_ClearContents_Resize()
Dim ws As Worksheet: Set ws = Sheets("Sheet2")
Dim ol As ListObject: Set ol = ws.ListObjects("MyTable")
' Delete table contents
ol.DataBodyRange.ClearContents
' Resize table
ol.Resize Range(ol.HeaderRowRange.Resize(2).Address)
End Sub
I hope someone can help me with this as it's driving me up the wall!
There are 5 non-contiguous cells in a worksheet that I want to copy to the next empty row on another worksheet whilst retaining the number formatting (which varies). I have this so far but am struggling working out how to retain formatting. Can anyone please help? Thanks I anticipation.
`With wsCalc
For bRun = 1 To 4
bData(bRun) = Application.Choose(bRun, .Range("g2"), .Range("b2"), .Range("R2"), .Range("Q14"))
Next bRun
End With
wSResults.Cells(Rows.Count, "a").End(xlUp).Offset(1).Resize(, 4).Value = bData
`
Here's a possible solution, using your hard-coded cell addresses. You will have to set wsCalc and wsResults to their proper worksheets. Slightly more elegant would be to define a "non-contiguous" range on your wsCalc sheet (select the 1st cell, keep Ctrl pressed and select the next one etc, then type a name in the drop-down box just to the left of the formula bar).
Option Explicit
Sub CopyWithFormat()
Dim wsCalc As Worksheet
Set wsCalc = ActiveSheet 'Or whatever your calc sheet is
Dim rngSource As Range
Set rngSource = wsCalc.[G2,B2,R2,Q14]
Dim wsResults As Worksheet
Set wsResults = ActiveSheet 'Or whatever your result sheet is
Dim clDest As Range
Set clDest = wsResults.Cells(Rows.Count, "a").End(xlUp).Offset(1)
Dim cl As Range
For Each cl In rngSource.Cells
clDest.Value = cl.Value
clDest.NumberFormat = cl.NumberFormat
Set clDest = clDest.Offset(1)
Next cl
End Sub
Instead of using .Value, try .Text. It retains formatting. See below.
Gary's Student is right, text is read only, it should be used for the input not the output.
bData(bRun) = Application.Choose(bRun, .Range("g2").Text, .Range("b2").Text, .Range("R2").Text, .Range("Q14").Text)
I also agree with other answer the entire code could be set up more straight forward.
I have a dataset on Worksheet "Results" and the dataset is in cells B8:K900 (Actual data in these cells, rest all cells have other meta information this dataset)
Each column of this data set refers to a certain variable like B column has Steam flow, C column has Steam temp etc.
I would like to use these values to plug into a calculator on another sheet, Row by row.
Eventually I will have results in 2 Cells on another sheet which I would like to bring back to Column L and M
Code so far, (I am getting error on first line "ws1.Range("B").Copy Destination:=ws2.Range("B6")" while debugging) :
Note: Goal Seek and Rerun are 2 macros which I would like run after one row of Scenario is in input, as these will help to get results. Hence I have added them in loop also
Any help would be appreciated.
Sub Goal_Seek()
Range("I33").GoalSeek Goal:=Range("P33").Value, ChangingCell:=Range("E3")
End Sub
Sub Rerun()
Do Until Range("P20") = Range("P22").Value
Range("P20") = Range("P22").Value
Loop
End Sub
Sub Calcs()
Dim wb As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet, ws4 As Worksheet, ws5 As Worksheet
Dim rng As Range
Set wb = ActiveWorkbook
Set ws1 = wb.Worksheets("Results")
Set ws2 = wb.Worksheets("PI Data")
Set ws3 = wb.Worksheets("Mole_avg")
Set ws4 = wb.Worksheets("eff")
Set ws5 = wb.Worksheets("FlueGas")
Set rng = ws1.Range("B8:M9")
For Each Row In rng.Rows
ws1.Range("B").Copy Destination:=ws2.Range("B6")
ws1.Range("C").Copy Destination:=ws2.Range("B3")
ws1.Range("D").Copy Destination:=ws2.Range("B4")
ws1.Range("E").Copy Destination:=ws2.Range("B5")
ws1.Range("G").Copy Destination:=ws2.Range("B7")
ws1.Range("H").Copy Destination:=ws2.Range("B8")
ws1.Range("I").Copy Destination:=ws2.Range("B9")
ws1.Range("J").Copy Destination:=ws2.Range("B10")
ws1.Range("K").Copy Destination:=ws2.Range("B11")
Application.Run "Goal_Seek"
Application.Run "Rerun"
ws3.Range("P17").Copy Destination:=ws1.Range("L")
ws3.Range("T22").Copy Destination:=ws1.Range("M")
Next Row
End Sub
I need to be able to copy different ranges of cells from one worksheet to another. For example A1:A4, C3:C7, D3:D6. I need the code to do the following:
Copy different data from those cells in the first worksheet (worksheet1) and paste them onto the same line but transposed on the second worksheet (worksheet2). I don't need to keep the original formatting.
When pasting the data I need it to find the last row and paste it below that row.
I can write a code which will do most of that but I only know how to get the code to do it for one cell range e.g. A1:A4.
Any help would be greatly appreciated.
OK, technically SO isn't a code-writing service but I use a code that does basically just that, so you might as well have it;
Sub CopyTransposeRange()
Dim shtCopy As Worksheet
Dim shtPaste As Worksheet
Dim rngCopy As Range
Set shtCopy = Sheets("Sheet1").Activate
Set shtPaste = Sheets("Sheet2")
Set rngCopy = Range("A1:A36")
'Put whatever's necessary in here to select the correct range
shtCopy.rngCopy.Copy
shtPaste.Activate
shtPaste.Range(Cells(shtPaste.UsedRange.Rows.Count + 1, 1), Cells(shtPaste.UsedRange.Rows.Count + 1, rngCopy.Rows.Count)).PasteSpecial _
xlPasteAll, xlPasteSpecialOperationNone, False, True
End Sub
Yes, I know activating sheets isn't best practice, but works for me ¯_(ツ)_/¯
hope it helps.
Try this code, please.
It will copy your selected range and transpose it in the roe 2 of second sheet:
Sub testCopyTransposedRanges()
Dim sh2 As Worksheet, inpRng As Range, lastCol As Long, arrTr As Variant
Set inpRng = Application.InputBox("Select range to be copied and transposed:", _
"Range Selection", Selection.Address, Type:=8)
If inpRng Is Nothing Then Exit Sub
arrTr = inpRng.value
If IsEmpty(arrTr) Then Exit Sub
Set sh2 = Worksheets("worksheet2") ' use here your sheet name!!!
lastCol = sh2.Cells(2, Cells.Columns.Count).End(xlToLeft).Column + 1
sh2.Cells(2, lastCol).Resize(, UBound(arrTr)).value = WorksheetFunction.Transpose(arrTr)
End Sub
It must be 'filterred' for 'Cancel', multi column selection etc. But this will be done only if such a solution matches your need. Otherwise, you must present the logic based on what to create an algorithm to automatically select the necessary ranges.
VBA CODE:
I have a series of tables (one per sheet) that need to increase or decrease in size dynamically, based on number that has been input by a user (on another sheet).
Each row in each of the tables needs to maintain the formatting and formulas from the rows above, whilst being "inserted".
I have used the below to successfully increase the size of the table with the correct formatting, but this only adds rows to the table.. and if someone clicks the macro button multiple times we could end up with far too many rows. Hence why I would like a dynamic table where the rows are determined by a number and it wouldn't matter if someone was click happy.
I have also made another attempt which does increase the size of the table, but it doesn't insert additional rows, so the table overlaps data that is in rows below the determined table. This attempt does not copy the formatting either... but this is all i have so far. Any help would be much appreciated, I've been working on this for a couple of months and can't find a suitable answer (after days of searching).
Sub InsertNumberOfRows()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim sh3 As Worksheet
Dim NBOFROWS As Range
Dim wkb As Workbook
Set NBOFROWS = Worksheets("Rates").Range("K4")
Set wkb = Workbooks("POD Automation10.1")
With wkb
Set sh1 = ActiveWorkbook.Sheets("POD Cost Plan")
Set sh2 = ActiveWorkbook.Sheets("Development Calculator")
Set sh3 = ActiveWorkbook.Sheets("Calculator Calculations")
sh1.Select
Rows("10:10").Select
Selection.EntireRow.Offset(1).Resize(NBOFROWS.Value).Insert Shift:=xlDown,
CopyOrigin:=xlFormatFromLeftOrAbove
sh2.Select
Rows("10:10").Select
Selection.EntireRow.Offset(1).Resize(NBOFROWS.Value).Insert Shift:=xlDown,
CopyOrigin:=xlFormatFromLeftOrAbove
sh3.Select
Rows("10:10").Select
Selection.EntireRow.Offset(1).Resize(NBOFROWS.Value).Insert Shift:=xlDown,
CopyOrigin:=xlFormatFromLeftOrAbove
End With
End Sub
NEXT ATTEMPT:
Sub InsertNumberOfRows()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim sh3 As Worksheet
Dim Value As Range
Dim wkb As Workbook
Dim rng As Range
Dim tbl As ListObject
Set Value = Worksheets("Rates").Range("K4")
Set wkb = Workbooks("POD Automation10.2")
With wkb
Set sh1 = ActiveWorkbook.Sheets("POD Cost Plan")
Set sh2 = ActiveWorkbook.Sheets("Development Calculator")
Set sh3 = ActiveWorkbook.Sheets("Calculator Calculations")
sh1.Select
Set tbl = ActiveSheet.ListObjects("POD_CostPlan_Tbl")
Set rng = Range("POD_CostPlan_Tbl[#All]").Resize(tbl.Range.Rows.Count + Value, tbl.Range.Columns.Count)
tbl.Resize rng
sh2.Select
Set tbl = ActiveSheet.ListObjects("TBL_UserEntry")
Set rng = Range("TBL_UserEntry[#All]").Resize(tbl.Range.Rows.Count + Value, tbl.Range.Columns.Count)
tbl.Resize rng
sh3.Select
Set tbl = ActiveSheet.ListObjects("TBL_Calculations")
Set rng = Range("TBL_Calculations[#All]").Resize(tbl.Range.Rows.Count + Value, tbl.Range.Columns.Count)
tbl.Resize rng
End With
End Sub
A better approach would be to use ListObject properties to add rows and columns. For example:
With ActiveSheet.ListObjects("Table1")
' Insert column at the end of table:
.ListColumns.Add
' Add row tp the bottom of table:
.ListRows.Add AlwaysInsert:= True
End With
If I were you, I would change all those to Tables, so everything (rows and columns) gets updated automatically.
https://www.thespreadsheetguru.com/blog/2014/6/20/the-vba-guide-to-listobject-excel-tables
Ctrl+T: This shortcut converts a range of related information to an Excel Table. To use this shortcut, just select any cell in a range of related data first.