I defining different ranges so that I can use them for graphs:
Sub rangesGRAPHS()
Dim count, counter, Erow, Prow1, Prow2, Urow1 As Long
Dim Dsrc1, Dsrc2, Dsrc3, Xsrc1, Xsrc2, Xsrc3 As Range
counter = 5
count = Application.CountA(Range("A:A"))
count = count + 3
While counter < count
If Range("Q" & CStr(counter)) = "ECO_BS" Then Erow = counter
If Range("Q" & CStr(counter)) = "PHO_BS" Then Prow2 = counter
counter = counter + 1
Wend
Prow1 = Erow + 1
Urow1 = Prow2 + 1
Dsrc1 = ("P5:P" & CStr(Erow))
Dsrc2 = ("P" & CStr(Prow1) & ":P" & CStr(Prow2))
Dsrc3 = ("P" & CStr(Urow1) & ":P" & CStr(count))
Xsrc1 = ("$C$5:$C$" & CStr(Erow))
Xsrc2 = ("$C$" & CStr(Prow1) & ":$C$" & CStr(Prow2))
Xsrc3 = ("$C$" & CStr(Urow1) & ":$C$" & CStr(count))
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range(Dsrc1)
ActiveChart.SeriesCollection(1).XValues = ("=SICALIS_Detail!" & Xsrc1)
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range(Dsrc2)
ActiveChart.SeriesCollection(1).XValues = ("=SICALIS_Detail!" & Xsrc2)
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range(Dsrc3)
ActiveChart.SeriesCollection(1).XValues = ("=SICALIS_Detail!" & Xsrc3)
Everything works except the line Xsrc3 = ("$C$" & CStr(Urow1) & ":$C$" & CStr(count)), which gives a error 91: object variable not set.
Upon debugging, I notice that Xsrc3 is set to nothing. However, all the other stuff works and it's written THE SAME WAY. If I comment it out the other stuff still works. I don't understand what is going on - let me know what's up!
It's not actually written the same way. In this line:
Dim Dsrc1, Dsrc2, Dsrc3, Xsrc1, Xsrc2, Xsrc3 As Range
the first 5 variables are actually declared as Variant and only the last is declared as a Range. You actually want them all to be String anyway, so use:
Dim Dsrc1 As String, Dsrc2 As String, Dsrc3 As String, Xsrc1 As String, Xsrc2 As String, Xsrc3 As String
Related
I've problems passing variable i into a loop that selects chart source values.
Sub Macro()
For i = 2 To 10
Windows("Book1").Activate
ActiveSheet.ChartObjects("Chart 1").Activate
ActiveChart.SetSourceData Source:=Range("Sheet1!$A$1:$F$1,Sheet1!$A$2:$F$2" _
)
Next i
End Sub
I want to change the series value Sheet1!$A$2:$F$2" and put i value there -> Sheet1!$A$i:$F$i"
I tried different approaches, but they didn't work
How to loop Ranges in VBA?
Excel vba Charting, editting the range
ActiveChart.SetSourceData Source:=Range("Sheet1!$A$1:$F$1,("Sheet1!$A$" & i & ":$F$" & i)" _
Okay, I found a workaround to my problem with selecting a value range differently.
Code below worked:
For i = 2 To 10
newName = "=Sheet1!$A$" + CStr(i)
newValues = "=Sheet1!$B$" + CStr(i) + ":$F$" + CStr(i)
ActiveChart.FullSeriesCollection(1).Name = newName
ActiveChart.FullSeriesCollection(1).Values = newValues
Next i
You have some unneeded quotes:
ActiveChart.SetSourceData Source:=Range("Sheet1!$A$1:$F$1,Sheet1!$A$" & i & ":$F$" & i)
Don't remember to assign i to str value
ActiveChart.SetSourceData Source:=Range("Sheet1!$A$1:$F$1,Sheet1!$A$" + cstr(i) + ":$F$" + cstr(i)
And the better way is createa variable
distinctrange = "Sheet1!$A$1:$F$1,Sheet1!$A$" + cstr(i) + ":$F$" + cstr(i)
ActiveChart.SetSourceData Source:=Range(distinctrange)
I try to create dynamic chart with VBA , for example I have 5 students I need to create 5 chart
for each students .
Sub Macro4()
Rows("2:2").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range("Sheet1!$2:$2")
Rows("3:3").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range("Sheet1!$3:$3")
Rows("4:4").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range("Sheet1!$4:$4")
Range("D12").Select
ActiveWorkbook.Save
End Sub
I create this using Macro only for test but I try do that as dynamically because if I have more then 100 students it will be difficult , etc..
I hope you guys help me
Thanks
Try the next way, please. No need of any selection. Selection is useless, it only consumes Excel resources:
Sub AddCharts()
Dim sh As Worksheet, ch As Shape, chartNo As Long
Dim prevWith As Long, i As Long
Set sh = ActiveSheet 'the sheet where the charts to be created
'chartNo = 5
chartNo = = Worksheets("Sheet1").Range("A" & rows.count).End(xlUp).row - 1
For i = 1 To chartNo
Set ch = sh.Shapes.AddChart
ch.Chart.ChartType = xlColumnClustered
ch.Chart.SetSourceData Source:=Range("Sheet1!$" & i + 1 & ":$" & i + 1)
ch.Chart.Parent.left = sh.Range("A1").left + prevWith 'here the first left chart position to be set
prevWith = ch.Chart.Parent.width 'the chart width, the next one will be added to its right side
Next i
ActiveWorkbook.Save
End Sub
Change your macro like this:
Sub Macro4(startRow As String, stud As Long)
For k = 1 To stud
Dim constr() As String
Dim cn As String
cn = ""
constr = Split(strtRow,":")
For Each c in constr
cn = cn & "$" & c & ":"
Next
cn = Left(cn, Len(cn) - 1)
Rows(strtRow).Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range("Sheet1!" & cn)
Dim str As String
str = ""
For each d in constr
str = str & (CInt(d)+1) & ":"
Next
str = Left(str, Len(str) - 1)
strtRow = str
Next
Now call like
Macro4("2:2",3)
Will do on 2:2 to 4:4
I have some a macro that assigns cataogories to various rows based on keywords.
This works well however is heavy on the machine as it is using the whole column.
How can I set it so that It will just search for these words until the last entry in column A:A?
Sub Categorise()
Sheets("Data").Range("I:I") = "=IF(OR(ISNUMBER(SEARCH(""*chair fault*"",B:B)),ISNUMBER(SEARCH(""*Chair noise*"",B:B))), ""Seating"", """")"
Sheets("Data").Range("L:L") = "=IF(OR(ISNUMBER(SEARCH(""*Arm fail*"",B:B)),ISNUMBER(SEARCH(""*Arm inhibition*"",B:B)),ISNUMBER(SEARCH(""*Gap in Arm*"",B:B)),ISNUMBER(SEARCH(""*No Arms*"",B:B)),ISNUMBER(SEARCH(""*All Arms*"",B:B))), ""Angles"", """")"
Sheets("Data").Range("M:M") = "=IF(OR(ISNUMBER(SEARCH(""*Couch*"",B:B)),ISNUMBER(SEARCH(""*Heating*"",B:B))), ""Comfort"", """")"
Sheets("Data").Range("J:J") = "=IF(OR(ISNUMBER(SEARCH(""*UDCD*"",B:B)),ISNUMBER(SEARCH(""*HDD flats*"",B:B)),ISNUMBER(SEARCH(""*HDD runner*"",B:B))), ""Runners"", """")"
Sheets("Data").Range("K:K") = "=IF(ISNUMBER(SEARCH(""*Cabbies*"",B:B)),""Cabbies four"","""")"
Sheets("Data").Range("N:N") = "=IF(ISNUMBER(SEARCH(""*Braker*"",B:B)),""Elec"","""")"
Sheets("Data").Range("O:O") = "=IF(OR(ISNUMBER(SEARCH(""*Camera*"",B:B)),ISNUMBER(SEARCH(""*chough*"",B:B)),ISNUMBER(SEARCH(""*Master MCC*"",B:B)),ISNUMBER(SEARCH(""*Standards*"",B:B)),ISNUMBER(SEARCH(""*screen*"",B:B)),ISNUMBER(SEARCH(""*RTSS*"",B:B)),ISNUMBER(SEARCH(""*Heads*"",B:B)),ISNUMBER(SEARCH(""*Harps faulty*"",B:B)),ISNUMBER(SEARCH(""*TMSC*"",B:B)),ISNUMBER(SEARCH(""*Blind*"",B:B))), ""Blinders"", """")"
Sheets("Data").Range("P:P") = "=IF(OR(ISNUMBER(SEARCH(""*faulting*"",B:B)),ISNUMBER(SEARCH(""*Marker MN*"",B:B)),ISNUMBER(SEARCH(""*Elec M5*"",B:B)),ISNUMBER(SEARCH(""* Alarm*"",B:B)),ISNUMBER(SEARCH(""*Graber*"",B:B)),ISNUMBER(SEARCH(""*catcher*"",B:B)),ISNUMBER(SEARCH(""*Circuit*"",B:B)),ISNUMBER(SEARCH(""*Sal fault*"",B:B)),ISNUMBER(SEARCH(""*Panter*"",B:B)),ISNUMBER(SEARCH(""*Vigilance*"",B:B))), ""Misc"", """")"
Sheets("Data").Range("F:F") = "=I:I&J:J&K:K&L:L&M:M&N:N&O:O&P:P"
Sheets("Data").Columns("I:P").EntireColumn.Hidden = True
Sheets("Data").Range("F1").FormulaR1C1 = "System"
End Sub
You can use the power of vba to build the formulas and save you having to typing so much, Your question said column A but your code shows column B. I have used column B,
Sub Categorise()
Dim wsData As Worksheet, lastrow As Long
Set wsData = ThisWorkbook.Sheets(1)
With wsData
lastrow = .Range("B" & .Rows.Count).End(xlUp).Row
End With
Dim ar(8), isN() As String
ar(0) = Array("Seating", "chair fault", "chair noise")
ar(1) = Array("Angles", "Arm fail", "arm inhibition", "Gap in Arm", "No Arms", "All Arms")
ar(2) = Array("Comfort", "Couch", "Heating")
ar(3) = Array("Runners", "UDCD", "HDD flats", "HDD runner")
ar(4) = Array("Cabbies four", "Cabbies")
ar(5) = Array("Elec", "Braker")
ar(6) = Array("Blinders", "camera", "chough", "Master MCC", "Standards", "screen", _
"RTSS", "Heads", "Harps faulty", "TMSC", "Blind")
ar(7) = Array("Misc", "faulting", "Marker MN", "Elec M5", "Alarm", _
"Grabber", "catcher", "Circuit", "Sal fault", "panter", "Vigilance")
With wsData
.Range("I1:I" & lastrow) = Query(ar(0))
.Range("L1:L" & lastrow) = Query(ar(1))
.Range("M1:M" & lastrow) = Query(ar(2))
.Range("J1:J" & lastrow) = Query(ar(3))
.Range("K1:K" & lastrow) = Query(ar(4))
.Range("N1:N" & lastrow) = Query(ar(5))
.Range("O1:O" & lastrow) = Query(ar(6))
.Range("P1:P" & lastrow) = Query(ar(7))
.Range("F1:F" & lastrow) = "=I:I&J:J&K:K&L:L&M:M&N:N&O:O&P:P"
.Columns("I:P").EntireColumn.Hidden = True
.Range("F1").FormulaR1C1 = "System"
End With
MsgBox "Done"
End Sub
Function Query(ar) As String
Dim isN() As String, i As Integer
ReDim isN(UBound(ar) - 1)
For i = 1 To UBound(ar)
isN(i - 1) = "ISNUMBER(SEARCH(""*" & ar(i) & "*"",B:B))"
Next
If UBound(ar) > 1 Then
Query = "=IF(OR(" & Join(isN, ",") & "), """ & ar(0) & ""","""")"
Else
Query = "=IF(" & isN(0) & ", """ & ar(0) & ""","""")"
End If
Debug.Print Query
End Function
I'm trying to use .clearcontents on range that is referenced by with some .offset, and I'm having trouble
I know that this works
Sub clear1_1()
Workbooks("xyz").Sheets("abc").range("A2:A3").ClearContents
End Sub
but if I try this it does not
Sub clear2()
Dim region As range
Set region = range("S509:AD618")
Workbooks("xyz").Worksheets("abc").range(region).ClearContents
end sub
I do understand from other postings, that it has something to do with object defyining, but I have no idea where I do mistake, what I need to write.
Final macro is run from one workbook, and is supposed to .clearcontents in other not activated workbook.
My code looks like this
sub Macro()
..... ton of code
Dim filename as string
dim sheetname as string
dim address3, address4 as string
filename = "xyz"
sheetname = "abc" ' both variables that are loaded in other part
address3 and address4 loaded in other part
'here is where i get the error
sheets(sheetname).Range(Range(address3).Offset(0, 12).Address & ":" & Range(address4).Offset(-1, 23)).ClearContents
end sub
I can probably bypass it with .value=""
But I'm looking to learn. Thank you for any response in advance.
EDIT 1
Hi Scott, doesn't make it. Posting bigger part of my code
If mapanchorsuccess = True And map1success = True And map2success = True Then
If Workbooks(Filename).Sheets(startws).Range(address1).Offset(10, 13).HasFormula = True Then
With Workbooks(wbm).Sheets("Report") 'report
.Range("A" & reportrow).Value = runnumber
.Range("B" & reportrow).Value = Filename
.Range("C" & reportrow).Value = Workbooks(Filename).Sheets(startws).Name
.Hyperlinks.Add anchor:=.Range("D" & reportrow), Address:=FilePath & Filename, SubAddress:=Workbooks(Filename).Sheets(startws).Name & "!A1"
.Range("E" & reportrow).Value = "Error"
.Range("F" & reportrow).Value = "rolling probably done already in this sheet"
reportrow = reportrow + 1
End With
Else
With Workbooks(Filename).Sheets(startws)
.Range(Range(address1).Offset(0, 12).Address & ":" & Range(address2).Offset(0, 14).Address).Copy _
Range(Range(address1).Address & ":" & Range(address2).Offset(0, 2).Address)
Application.CutCopyMode = False
.Range(Range(address1).Offset(0, 16).Address & ":" & Range(address2).Offset(0, 16).Address).Copy _
Range(Range(address1).Offset(0, 3).Address & ":" & Range(address2).Offset(0, 23).Address)
Application.CutCopyMode = False
With Workbooks(wbm).Sheets("Report") 'report
.Range("A" & reportrow).Value = runnumber
.Range("B" & reportrow).Value = Filename
.Range("C" & reportrow).Value = Workbooks(Filename).Sheets(startws).Name
.Hyperlinks.Add anchor:=.Range("D" & reportrow), Address:=FilePath & Filename, SubAddress:=Workbooks(Filename).Sheets(startws).Name & "!A1"
.Range("E" & reportrow).Value = "Completed"
.Range("F" & reportrow).Value = "region1 rolled forward"
reportrow = reportrow + 1
End With
.Range(Range(address3).Offset(0, 12).Address & ":" & Range(address4).Offset(-1, 23).Address).Copy _
Range(Range(address3).Address & ":" & Range(address4).Offset(-1, 11).Address)
'///// here the error 1004 occurs
.Range(Range(address3).Offset(0, 12).Address & ":" & Range(address4).Offset(-1, 23).address).clearcontent
End With
End If
End If
The workbook and sheet need to be set with the variable.
Then when using it since it is a range itself just refer to it.
Sub clear2()
Dim region As range
Set region = Workbooks("xyz").Worksheets("abc")range("S509:AD618")
region.ClearContents
end sub
As to your next code; that is a different problem. The ranges inside the () need to allocated to the correct sheet parentage or it will use the active sheet.
The easiest is with a With block:
With sheets(sheetname)
.Range(.Range(address3).Offset(0, 12), .Range(address4).Offset(-1, 23)).ClearContents
End With
I had this same issue, but it turned out to be very simple. I had a row of cells merged together between columns E and F, so when I used this command I had to set the ClearContents from the top corner of my E column to the bottom row of my F column.
What did not work:
Range("E1:E10").Clear Contents
What did work:
Range("E1:F10").ClearContents
I can't believe such a simple thing left me so thwarted.
I have SUMIF running really really slow. My data has 14,800 Rows and 39 Columns.
I do the following:
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
EDITED TO ADD more potentially relevant code that may be interacting with the SUMIF command
It may be relevant to the speed issue so I'll mention it. I get the user to open a file from wherever they may have stored the report. The file then stays open. Maybe that is a problem. I don't know if it should be some other way.. like I close it but keep the address in mind or something??
FilterType = "Text Files (*.txt),*.txt," & "Comma Separated Files (*.csv),*.csv," & "ASCII Files (*.asc),*.asc," & "All Files (*.*),*.*"
FilterIndex = 4
Title = "File to be Selected"
File_path = Application.GetOpenFilename(FileFilter:=FilterType, FilterIndex:=FilterIndex, Title:=Title)
If File_path = "" Then
MsgBox "No file was selected."
Exit Sub
End If
Set wbSource = Workbooks.Open(File_path)
Original_Name = ActiveWorkbook.Name
If ActiveSheet.AutoFilterMode Then
ActiveSheet.AutoFilterMode = False
End If
Set wb1 = ActiveWorkbook
Set ws1 = wb1.Worksheets("Sheet1")
With ws1
FinalColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
FinalRow = .Range("B" & .Rows.Count).End(xlUp).Row
For j = 1 To FinalColumn
If .Cells(1, j).Value = "Effec.Date" Then
Effective_Date_Column = j
ElseIf .Cells(1, j).Value = "FolderId" Then
FolderId_column = j
ElseIf .Cells(1, j).Value = "FolderNotional" Then
FolderNotional_column = j
End If
Next j
'range_Total_Folder_Fixed = .Cells(2, Total_Folder_Column).Address & ":" & .Cells(FinalRow, Total_Folder_Column).Address
range_FolderId_Fixed = .Cells(2, FolderId_column).Address & ":" & .Cells(FinalRow, FolderId_column).Address
range_FolderId_Cell = .Cells(2, FolderId_column).Address(RowAbsolute:=False, ColumnAbsolute:=False)
range_FolderNotional_Fixed = .Cells(2, FolderNotional_column).Address & ":" & .Cells(FinalRow, FolderNotional_column).Address
Everything runs in 8-10 seconds until we come to the lie below. Now the total time jumps to a 150 seconds.
.Range(range_Total_Folder_Fixed).Formula = "=SUMIF(" & range_FolderId_Fixed & "," & range_FolderId_Cell & "," & range_FolderNotional_Fixed & ")"
Am I doing something wrong? Is there a better (more efficient) way to write a general formula?
EDIT: Code generated Raw Formula
Some of the excel worksheet functions in my code:
.Range(range_Isnumber).Formula = "=(RIGHT(" & range_TradeId_cell & ",2)<> ""IB"")*1"
.Range(range_Is_IB).Formula = "=(RIGHT(" & range_TradeId_cell & ",2)= ""IB"")*1"
.Range(range_Exceptions).Formula = "=(SUMIF(" & range_FolderId_Fixed & "," & range_FolderId_Cell & "," & range_Isnumber_fixed & ")= COUNTIF(" & range_FolderId_Fixed & "," & range_FolderId_Cell & "))*1+(SUMIF(" & range_FolderId_Fixed & "," & range_FolderId_Cell & "," & range_Is_IB_fixed & ")= COUNTIF(" & range_FolderId_Fixed & "," & range_FolderId_Cell & "))*1 "
.Range("C13").FormulaR1C1 = "=SUM(IF(FREQUENCY(MATCH([SCL_FL_2013_11_30.xlsx]Rest!R2C2:R2321C2,[SCL_FL_2013_11_30.xlsx]Rest!R2C2:R2321C2,0),MATCH([SCL_FL_2013_11_30.xlsx]Rest!R2C2:R2321C2,[SCL_FL_2013_11_30.xlsx]Rest!R2C2:R2321C2,0))>0,1))"
So Stuff like
Range("I2")=SUMIF($H$2:$H$5,H2,$G$2:$G$5)
Where the data could be like
RowG RowH RowI
Alice 1 4
Alice 3 4
Bob 9 17
Bob 8 17
Dan 2 2
EDIT2 : Implementing Sam's solution, I am getting errors:
Set range_FolderId_Fixed = .Range(.Cells(2, FolderId_column), .Cells(FinalRow, FolderId_column))
Set range_FolderId_Cell = .Range(.Cells(2, FolderId_column),.Cells(FinalRow, FolderId_column))
Set range_FolderNotional_Fixed = .Range(.Cells(2, FolderNotional_column), .Cells(FinalRow, FolderNotional_column))
Set range_Total_Folder_Fixed = .Range(.Cells(2, Total_Folder_Column), .Cells(FinalRow, Total_Folder_Column))
.Range(range_Total_Folder_Fixed).Value = SumIf_func(range_FolderId_Fixed, range_FolderId_Cell, range_FolderNotional_Fixed)
I am getting a type application defined or object defined error in the line below.
.Range(range_Total_Folder_Fixed).Value = SumIf_func(range_FolderId_Fixed, range_FolderId_Cell, range_FolderNotional_Fixed)
I have no idea what to do next.
Ok this is what I came up with
Public Function SumIf_func(rng As Range, _
criteria As Range, _
sumRange As Range) As Variant()
Dim rngArr() As Variant
Dim sumArr() As Variant
Dim criteriaArr() As Variant
Dim returnArr() As Variant
Dim temp As Double
rngArr = rng.Value2
sumArr = sumRange.Value2
criteriaArr = criteria.Value2
If UBound(sumArr) <> UBound(rngArr) Then _
Err.Raise 12345, "SumIf_func", "Sum range and check range should be the same size"
If UBound(sumArr, 2) <> 1 Or UBound(rngArr, 2) <> 1 Then _
Err.Raise 12346, "SumIf_func", "Sum range and check range should be a single column"
ReDim returnArr(1 To UBound(criteriaArr), 1 To 1)
For c = LBound(criteriaArr) To UBound(criteriaArr)
returnArr(c, 1) = Application.WorksheetFunction.SumIf(rng, criteriaArr(c, 1), sumRange)
Next c
SumIf_func = returnArr
End Function
This function takes in three ranges:
The range to check
The range where the criteria are
The range where the values to sum are
The range to check and the sum range should both be the same length and only be 1 column across.
The array that is returned will be the same size as the criteria array..
Here is an example of usage:
Public Sub test_SumIf()
Dim ws As Worksheet
Set ws = Sheet1
Dim rng As Range, sumRng As Range, criteria As Range
Set rng = ws.Range("A1:A100")
Set sumRng = ws.Range("B1:B100")
Set criteria = ws.Range("C1:C10")
ws.Range("D1:D10").Value = SumIf_func(rng, criteria, sumRng)
End Sub