I was just curious if there was an easy way to almost do a cut in page with vba code. Let me explain a bit.
Lets Say we have a NamedRange Called LookUpTableData$A1:$D10
each cell in the range has different data, and by data i mean contents, not datatype.
So lets say i retrieve the range in VBA like this.
CompleteModifiedRange = Range("LookUpTableData")
'Now I make some changes to the data
CompleteModifiedRange.Cells(1,1).Value = Blah
CompleteModifiedRange.Cells(2,1).Value = Blah2
So the real question is, How can i sort of paste the entire range back in place without having to loop through all the cells and set them? Kind of like this.
Set Range("LookUpTableData").Range = CompleteModifiedRange
Is there such a way?
You've basically almost answered your own question. Because you didn't use Set, your CompleteModifiedRange variable actually contains an array, and therefore you wouldn't use Cells with it:
Dim CompleteModifiedRange As Variant
CompleteModifiedRange = Range("LookUpTableData").Value
'Now I make some changes to the data
CompleteModifiedRange(1,1).Value = Blah
CompleteModifiedRange(2,1).Value = Blah2
Range("LookUpTableData").Value = CompleteModifiedRange
Related
This is proper basic but I'm struggling here. I need the range of rows of a data source in a graph to extend or retract by a value I have in "J5". "J5" changes dynamically and I can use a call function for it to work in the graph. Because of the way the charts are set up it has to be this way. My code so far is:
Sub Updatecodelengh()
Dim i As Integer
Dim G As Worksheet
Set G = Sheet1
i = G.Range("J5")
ActiveSheet.ChartObjects("GanttChart").Activate
ActiveChart.SeriesCollection(16).Values = "='Gantt'!$L$3:$L$4"
End Sub
Where it says "='Gantt'!$L$3:$L$4" I need the range of the chart data to start on $L$3 and extend downwards by the value obtained in J5. Thanks for any help
Do you mean simply
ActiveChart.SeriesCollection(16).Values = "='Gantt'!$L$3:$L$" & i
However, you should check if J5 contains a valid number to prevent runtime errors.
A small hint: When dealing with row and column numbers in VBA, always use datatype long.
I am new to VBA and am having problems learning the rules of variables (I think that's the problem here).
I have two worksheets in a spreadsheet. I need to make code that automatically hides a row on worksheet 2 if that same value in column a is on worksheet 1, column a.
Here's one of the variations of code I've tried:
Dim Sheet2Value As Variant
Dim Sheet1Value As Variant
'
Sheet2Value = Sheets("Sheet2").Range("A:A").Value
Sheet1Value = Sheets("Sheet1").Range("A:A").Value
'
If Sheet2Value = Sheet1Value Then
Sheets("BMAC=N").EntireRow.Hidden = False
Else
Sheets("BMAC=N").EntireRow.Hidden = True
End If
I get a type mismatch error but I'm not sure exactly why. I chose variant because I don't know what I'm doing, but both columns in excel will be set to "General".
Can anyone help with this? What concept am I missing?
Thanks so much for your time.
Few things:
you cannot compare entire column:
Sheet2Value = Sheets("Sheet2").Range("A:A").Value
you need to loop through the collection of cells, see this: Fast compare method of 2 columns
you cannot hide row without defining a range to hide
Sheets("BMAC=N").Range("Some_address").EntireRow.Hidden
Finally, i'd suggest to change your code to shortest way:
Sheets("BMAC=N").Range("A1").EntireRow.Hidden = (value1<>value2)
Good luck!
I'm struggling a bit with VBA syntax tonight, and would appreciate your help.
I have a Userform that takes input through RefEdit fields, and stores that as a variable (range). (This is done through
set DurationRange = range(me.refedit1.value)
which was an earlier question of mine tonight.
This user form takes this range input, and outputs the range into a different sheet for further processing. What I would like to do is basically output the variable again.
I'm trying that with this code:
with worksheets("Data Output")
.range("a1").offset(0, counter) = "Durations" 'this line just creates a header cell
.range("a2").offset(0, counter) = DurationsRange 'this line should output the range into cell a2
End with
But although this outputs the string, it does nothing for the range. What is the proper method to output a range? I know I could do a for each loop, but I have so many ranges that that seems incredibly inefficient.
There are some possible answers:
1st. if your DurationRange is a single cell range than you need to improve your code only in this line:
.range("a2").offset(0, counter) = DurationsRange.Value 'Value property is important here
2nd. if your DurationRange consists of one single column and some rows then you could possibly use this solution:
.range("a2").offset(0, counter).Resize(DurationRange.Rows.Count) = DurationsRange.Value 'Value property is important here, too
Obviously, there are some other options which could be solved in similar way to 2nd example above.
I'm looking to find a way to set the current chart as whatever I have in a a cell in an array. For example, my array will have Chart_1_4301 as the first listing, and I then want to set the chart, which is also named Chart_1_4301, as the CurrentChart.
Rather than saying
If Array_Name(i) = "Chart_1_4301" Then
'Some sort of code
End If
If Array_Name(i) = "Chart_1_4404" Then
'Some sort of code
End If
If Array_Name(i) = "Chart_1_4552" Then....
ect. Is there a way to set the CurrentChart as the name of the chart, whose name is stored in a cell?
I just want to say something like: Set CurrentChart = Array_Name(i)
I know something like this is possible in MATlab (which is the only other programming I've done) but I don't know the syntax in VBA. Any help is greatly appreciated!
For better assistance, it is helpful to post more of your code. Varocarbas gave some suggestions, above.
I will give you another suggestion based on a different interpretation of your incomplete question. Since I do not know what Type is the CurrentChart (i.e., is it a ChartObject or a Chart?)
Assuming you're doing some sort of loop/iteration over the array of names, and you want to operate on each chart in sequence:
For i = lBound(Array_Name) to UBound(Array_Name)
Set CurrentChart = ActiveSheet.ChartObjects(Array_Name(i))
Next
In my excel VBA code, I need to move some data from a range to another sheet.
As of now, I'm iterating through the range and copying the values like this:
For offset = 0 To 101
ActiveWorkbook.Sheets(Sheet).Range("C3").offset(offset, 0).Value = ActiveSheet.Range("D4").offset(offset, 0).Value
Next offset
However, it takes almost a minute to iterate and copy the values for the 100 cells.
Would I be better off using Copy-Paste programatically, or is there a way to copy for the entire range at once? Something like:
ActiveWorkbook.Sheets(Sheet).Range("C3:C102").Value = ActiveSheet.Range("D4:D104").Value
You can read the entire range at once into a Variant array, and then write it back to another range. This is also quick, flickerless, and has the added bonus that you can code some operations on the data if you are so inclined.
Dim varDummy As Variant
varDummy = ActiveSheet.Range("D4:D104")
' Can insert code to do stuff with varDummy here
Workbook.Sheets(Sheet).Range("C3:C103") = varDummy
This I learned the hard way: Avoid Copy/Paste if at all possible! Copy and Paste use the clipboard. Other programs may read from / write to the clipboard while your code is running, which will cause wild, unpredictable results.
Also, it's generally a good idea to minimize the number of interactions between VBA and Excel, because they are slow. Having such interactions in a loop is multiply slow.
So, silly me did not try before posting here. Apparently, I can move data for an entire range this way:
Workbook.Sheets(Sheet).Range("C3:C102").Value = ActiveSheet.Range("D4:D104").Value
Its as fast as copy-paste without the switching of sheets.
Iterating through the range using a for loop takes about 45s for 100 cells, while the above two options are instant.
You can speed up code and stop flickering with:
Application.ScreenUpdating = False
'YOUR CODE
Application.ScreenUpdating = True
More: http://www.ozgrid.com/VBA/excel-macro-screen-flicker.htm
Columns("A:Z").Select
Selection.Copy
Sheets("Sheet2").Select
Range("A1").Select
ActiveSheet.Paste
That will copy columns A to Z from Sheet 1 to Sheet 2. This was generated by recording the macro. You can also apply it to ranges with something like this:
Range("D4:G14").Select
Selection.Copy
Sheets("Sheet2").Select
Range("D4").Select
ActiveSheet.Paste
Is this something like what you're after?
If you need anything specific and you can do it manually (e.g. copy and paste), record the macro to get the VBA code for it.
Copy and pasting has a decent amount of overhead in VBA, as does dealing with ranges like that. Its been a while since I have done VBA but if I recall correctly the fastest way to do something like this is to write the values you want into an array and then use the Resize function. So something like this:
Option Base 0
Dim firstrow as integer
Dim lastrow as integer
Dim valuesArray() as Long
Dim i as integer
//Set firstrow and lastrow however you deem appropriate
...
//Subtracing first row from last row gets you the needed size of the 0 based array
ReDim valuesArray(lastrow-firstrow)
for int i = 0 to (lastrow-firstrow)
valuesArray(i)=Cells(i+firstrow, COLUMNNUMBER).value
next i
Of course replace COLUMNNUMBER with whatever column it is you are iterating over. This should fill your array with your desired values. Then pick your destination cell and use Resize to put the values in. So if your destination cell is D4:
Range("D4").Resize(UBound(valuesArray)+1, 0).value = valuesArray
That write all the values in the array starting at D4 and going down to as many cells are in the array. Slightly more complicated but if you are going for speed I don't think I have ever come up with anything faster. Also I did this off the top of my head so please test and make sure that you don't cut off a cell here and there.
That OZGrid page has very useful info - http://www.ozgrid.com/VBA/SpeedingUpVBACode.htm
In my case, I need the formatting to be copied as well so I have been using this:
Sheet1.Range("A1:A200").Copy Destination:=Sheet2.Range("B1")
but was still having very slow execution - to the point of locking up the application - I finally found the problem - at some point in the past a number of empty text boxes got into my page - and while they were copied each time my code ran they were not erased by my code to clear the working area. The result was something like 4,500 empty text boxes - each of which was copy and pasted by even the code above.
If you use Edit - Go To... - Click on Special - then choose Objects - and you don't see anything that is good - if you see a bunch of objects that you were not aware of on your page that is not good.