I am trying to use an existing named range to reference different rows (the columns should be the same). Right now I have the following:
Dim DetailONE, DetailONW, DetailW, DetailQc As Range
Set DetailONE = Sheet11.Range("CM12:EG13")
Set DetailONW = Sheet11.Range("EI12:GC13")
Set DetailW = Sheet11.Range("GE12:HO13")
Set DetailQc = Sheet11.Range("HQ12:IT13")
And then I refer to those named ranges but I get an Application defined or object defined error with the following. Does anyone know why? I don't know if I need the .Address part afterwards either or if I can forego this.
Dim OntarioWestDet, OntarioEastDet, WestDet, QuebecDet As Range
Set OntarioWestDet = Sheet11.Range(DetailONW.Address).Offset(3, 0).Resize(300, 0)
Set OntarioEastDet = Sheet11.Range(DetailONE).Offset(3, 0).Resize(300, 0)
Set WestDet = Sheet11.Range(DetailWe).Offset(3, 0).Resize(300, 0)
Set QuebecDet = Sheet11.Range(DetailQc).Offset(3, 0).Resize(300, 0)
This works for me (there is a typo in one of your names
Sub x()
Dim DetailONE As Range, DetailONW As Range, DetailW As Range, DetailQc As Range
Set DetailONE = Sheet11.Range("CM12:EG13")
Set DetailONW = Sheet11.Range("EI12:GC13")
Set DetailW = Sheet11.Range("GE12:HO13")
Set DetailQc = Sheet11.Range("HQ12:IT13")
Dim OntarioWestDet As Range, OntarioEastDet As Range, WestDet As Range, QuebecDet As Range
Set OntarioWestDet = DetailONW.Offset(3, 0).Resize(300)
Set OntarioEastDet = DetailONE.Offset(3, 0).Resize(300)
Set WestDet = DetailW.Offset(3, 0).Resize(300)
Set QuebecDet = DetailQc.Offset(3, 0).Resize(300)
End Sub
Related
I have a template, when opened opens up a user-form for specified data. But how can I delete the data inputted (bookmarks), if I want to rerun the macro to add new data. Currently it just adds on to whatever is filled.
Private Sub Cancelbut_Click()
PInfo.Hide
End Sub
Private Sub OKbut_Click()
Dim CompamyName As Range
Dim CompanyName2 As Range
Set CompanyName = ActiveDocument.Bookmarks("CName").Range
Set CompanyName2 = ActiveDocument.Bookmarks("CName2").Range
CompanyName.Text = Me.TextBox1.Value
CompanyName2.Text = Me.TextBox1.Value
Dim VendorName As Range
Set VendorName = ActiveDocument.Bookmarks("VName").Range
VendorName.Text = Me.TextBox2.Value
Dim ProjectName As Range
Dim ProjectName2 As Range
Set ProjectName = ActiveDocument.Bookmarks("PName").Range
Set ProjectName2 = ActiveDocument.Bookmarks("PName2").Range
ProjectName.Text = Me.TextBox3.Value
ProjectName2.Text = Me.TextBox3.Value
Dim ProjectCode As Range
Set ProjectCode = ActiveDocument.Bookmarks("PCode").Range
ProjectCode.Text = Me.TextBox4.Value
Me.Repaint
PInfo.Hide
End Sub
How would someone go about clearing the existing data? Feel like this would help anyone trying to work with bookmarks in word. I have attempted to do it, but end up deleting the bookmarks.
Appreciate the help!
Writing to a bookmark (whether as a user or using code) deletes the bookmark - this is by-design. When working with VBA, however, you have a work-around not easily available to the user...
If you first assign a Range object to the bookmark's Range, the text you assign to the Range can subsequently be bookmarked again. Since you write to numerous bookmarks, best to put these actions into a separate procedure, rather than repeat them throughout your code, as proposed below.
Tip: You can save yourself some code if you put REF fields (cross-references) in for the second bookmarks, where you write the information twice.
Function WriteToBookmarkRetainBookmark(rng As Object, content As String)
Dim sBkmName As String
sBkmName = rng.Bookmarks(1).Name
rng.Text = content
rng.Document.Bookmarks.Add sBkmName, rng
End Function
Private Sub OKbut_Click()
Dim CompamyName As Range
Dim CompanyName2 As Range
Set CompanyName = ActiveDocument.Bookmarks("CName").Range
Set CompanyName2 = ActiveDocument.Bookmarks("CName2").Range
WriteToBookmarkRetainBookmark(CompanyName, Me.TextBox1.Value)
WriteToBookmarkRetainBookmark(CompanyName2, Me.TextBox1.Value)
Dim VendorName As Range
Set VendorName = ActiveDocument.Bookmarks("VName").Range
WriteToBookmarkRetainBookmark(VendorName, Me.TextBox2.Value)
Dim ProjectName As Range
Dim ProjectName2 As Range
Set ProjectName = ActiveDocument.Bookmarks("PName").Range
Set ProjectName2 = ActiveDocument.Bookmarks("PName2").Range
WriteToBookmarkRetainBookmark(ProjectName, Me.TextBox3.Value)
WriteToBookmarkRetainBookmark(ProjectName2, Me.TextBox3.Value)
Dim ProjectCode As Range
Set ProjectCode = ActiveDocument.Bookmarks("PCode").Range
WriteToBookmarkRetainBookmark(ProjectCode, Me.TextBox4.Value)
Me.Repaint
PInfo.Hide
End Sub
I am trying to use Application.AverageIfs and I need to divide the answer by 3. I tried this way:
Range("C1:C676") = (Application.IfError(Application.AverageIfs(Sheets(modelName).Range("R:R"....
Sheets(modelName).Range("U:U"), "OGV"), "0") / 3)
and also without the brackets round the first application and the final 3 but this gives a type mismatch error.
Nesting it within Application.Quotient works but it only gives the integer part of the answer and I need the decimal as well. Is there a decimal-friendly alternative? I would prefer to continue to use the application syntax rather than putting range().formula = "=averageifs( if its possible.
Edit: after J.Fox's suggestion I have broken the formula parts into variables. The problem seems to be the criZFrom and criZTo variables which use a range in a separate sheet as criteria. The formula works fine if I replace these variables with "1" and "2" respectively. The code is now:
Set rng = Sheets(wsName).Range("C1:C676")
Set avgCol = Sheets(modelName).Range("M:M")
Set colZFrom = Sheets(modelName).Range("G:G")
Set criZFrom = Sheets(wsName).Range("A1:A676")
Set colZTo = Sheets(modelName).Range("H:H")
Set criZTo = Sheets(wsName).Range("B1:B676")
Set colTime = Sheets(modelName).Range("V:V")
Set colVType = Sheets(modelName).Range("U:U")
criVType = "OGV"
criAM = "AM"
Range("A1:A676").Formula = "=roundup(row()/26,0)"
Range("B1:B676").Formula = "=if(mod(row(),26)=0,26,mod(row(),26))"
rng = Application.AverageIfs(avgCol, colZFrom, criZFrom, colZTo, criZTo, colTime, criAM, colVType, criVType) / 3
Here is some sample data:
from sheets(modelName), this has the data that I am trying to average and most of the criteria ranges:
From sheets(wsName), this has the criteria for the problem variables and is where I want the result to appear (in column C):
Looks like you're missing a closing parenthesis after "OGV") to close out the AverageIfs function, i.e.:
Range("C1:C676") = Application.IfError(Application.AverageIfs(Sheets(modelName).Range("R:R", Sheets(modelName).Range("U:U"), "OGV")), 0) / 3
Also, not sure if .... was just for on here or in your code, but you'd want to use _ instead, as in:
Range("C1:C676") = _
Application.IfError(Application.AverageIfs(Sheets(modelName).Range("R:R", _
Sheets(modelName).Range("U:U"), "OGV")), 0) / 3
Edit: If you're still getting an error, I suggest breaking up your formula into component parts and assigning each part to a variable so you can troubleshoot exactly where the issue is, like so:
Sub test()
Dim rng As Range, col1 As Range, col2 As Range, str As String, modelName As String
modelName = "Sheet1"
Set rng = Range("C1:C676")
Set col1 = Sheets(modelName).Columns(18)
Set col2 = Sheets(modelName).Columns(21)
str = "OGV"
rng = Application.IfError(Application.AverageIfs(col1, col2, str), 0) / 3
End Sub
Can we see some sample data? It might be an issue of what order the arguments are being passed for the AverageIfs function.
Edit 2: I think I might see what the problem is. You're using the AverageIfs function with the intention of validating each line separately based on the specific criteria for each line by using a range for Arg3 and Arg5 instead of single values, which AverageIfs doesn't like. Criteria for Ifs functions will always need to be a single value instead of a range of values. Instead, I think you would need to iterate each line separately using a loop, like this:
Set avgCol = Sheets(modelName).Range("M:M")
Set colZFrom = Sheets(modelName).Range("G:G")
Set colZTo = Sheets(modelName).Range("H:H")
Set colTime = Sheets(modelName).Range("V:V")
Set colVType = Sheets(modelName).Range("U:U")
criVType = "OGV"
criAM = "AM"
Range("A1:A676").Formula = "=roundup(row()/26,0)"
Range("B1:B676").Formula = "=if(mod(row(),26)=0,26,mod(row(),26))"
Dim x as Long
Dim t as Variant
For x = 1 To 676
Set criZFrom = Sheets(wsName).Range("A" & x)
Set criZTo = Sheets(wsName).Range("B" & x)
Set Rng = Sheets(wsName).Range("C" & x)
t = Application.WorksheetFunction.AverageIfs(avgCol, colZFrom, criZFrom.Value, colZTo, criZTo.Value, colTime, criAM, colVType, criVType)
t = CDbl(t / 3)
Rng.Value = t
Next x
I'm trying to use a variable within a formula but the result I am getting is FALSE, when it should be returning a Lookup value, starting from the bottom of a table and going up.
Private Sub NewTaxCode()
Dim TaxCode2 As Long
Dim B As Range
Dim TaxCode3 As Range
Dim TaxCode4 As Range
Worksheets("P11Combined").Activate
Set B = Range("A:A")
Worksheets("E'ee Details").Range("U1").Value = "=Match(RC[-4],P11Combined!C[-18],0)"
TaxCode2 = Worksheets("E'ee Details").Range("U1").Value
Set TaxCode3 = Range("A:A").Find(What:="TAX:", After:=B(TaxCode2))
Set TaxCode4 = Range(TaxCode3.Address).End(xlDown).Offset(1, 2)
TaxCode5 = Range(TaxCode4.Address).FormulaR1C1 = "=LOOKUP(2,1/(R[-12]C:R[-1]C<>"" ""),(R[-12]C[-1]:R[-1]C[-1]))"
The last line is where I am having the issues. The formula works fine on a spreadsheet but I can't get it to work in VBA.
The last line of your code is of the format
variable = logical_expression
and is setting a variable (TaxCode5) to be either True or False depending on whether or not the formula in the cell referred to by TaxCode4 is the same as the one in the code.
It does not modify the formula in the cell referred to by TaxCode4.
It appears you want:
Private Sub NewTaxCode()
Dim TaxCode2 As Long
Dim B As Range
Dim TaxCode3 As Range
Dim TaxCode4 As Range
Dim TaxCode5 As Variant
Set B = Worksheets("P11Combined").Range("A:A")
Worksheets("E'ee Details").Range("U1").FormulaR1C1 = "=Match(RC[-4],P11Combined!C[-18],0)"
TaxCode2 = Worksheets("E'ee Details").Range("U1").Value
Set TaxCode3 = B.Find(What:="TAX:", After:=B(TaxCode2))
Set TaxCode4 = TaxCode3.End(xlDown).Offset(1, 2)
TaxCode4.FormulaR1C1 = "=LOOKUP(2,1/(R[-12]C:R[-1]C<>"" ""),(R[-12]C[-1]:R[-1]C[-1]))"
TaxCode5 = TaxCode4.Value
'...
End Sub
I am trying to build some code that inserts a name and email address in to the next open row from the next row in the loop. I am getting an error in Set = Number of Emails line and I am not sure why.
Sub Email_Copy()
Dim Data As Worksheet
Set Data = ActiveWorkbook.Sheets("Data")
Dim Email_Database As Worksheet
Set Email_Database = ActiveWorkbook.Sheets("Email_Database")
Dim Number_Of_Emails As Integer
Set Number_Of_Emails = Data.Range("L6002")
Dim Total_Emails As Long
Set Total_Emails = Email_Database.Range("D2")
Dim X As Long
For X = 1 To Number_Of_Emails
Set Email_Database.Range("B3").Offset(Total_Emails, 0) = Data.Range("D3").Offset(Number_Of_Emails, 0)
End Sub
You declared Number_Of_Emails As Integer but then tried to set it to a range so it's a type mismatch. You can simply do
Number_Of_Emails = Data.Range("L6002").value
Edit: to plagarize Scott Holtzman's comment verbatim
Set is only required with Object Type variables (hence the error). A
Range variable is an Object Type. An Integer, being a number, is not
an object type. (String is not on object either). Worksheet is an
Object Type.
Ok, so I have a table of names in one column and corresponding numbers in another. Most names appear more than once and each time with a different number. The table is likely to be added to in the future. I'm trying to write a VBA macro that will output each name once and the total sum of the numbers attached to them on a separate sheet. I haven't used VBA in like 8 months and I'm really rusty. Suggestions?
remember to add the reference microsoft scripting runtime, i believe. u would need to use dictionary here.
Sub test()
Dim var As Variant
Dim rng As Range
Set rng = Range("A1:A100")
Dim dico As Dictionary
Set dico = New Dictionary
For Each var In rng.Cells
if dico.Exists(var.value) Then
dico(var.value) = dico(var.value) + var.offset(0,1).value
else
dico.Add var.value, var.offset(0,1).value
end if
Next var
Set rng = Range("C1")
Dim i as double
i = 0
For Each var In dico.keys
rng.offset(i).value = var
rng.offset(i,1).value = dico(var)
Next var
End sub