Hi. I have many columns of numerical data with headings starting in Column B, Row 8 (all the way to Column GI in this instance but the number of columns is not always the same).
The range of values starts in Row 9 of each column (ie. just below the headings). Let's say Column C's data stops at Row 59, Column D's data stops at Row 74, and so on... each column length is different but never more than 5000 (hence the '5000' in the code below).
I would like to find the maximum value in each column and have this value placed in Row 2 of each column.
Here's my code that doesn't work...
(Note: MultiLetter is a function I have defined to convert column integer identifiers into the normal letter identifiers... ie. "3" is Column C).Sub MAXVALUES() Dim LASTCOL_I As Integer LASTCOL_I = ActiveSheet.UsedRange.Columns.Count Dim CurrentCol_I As Integer CurrentCol_I = 2 Dim CurrentCol_S As String CurrentCol_S = MultiLetter(CurrentCol_I) Do Until CurrentCol_I = LASTCOL_I + 1 Cells(CurrentCol_I, 2) = WorksheetFunction.Max(CurrentCol_S & "9" & ":" & CurrentCol_S & "5000") CurrentCol_I = CurrentCol_I + 1 CurrentCol_S = MultiLetter(CurrentCol_I) Loop End Sub
I get a VisualBasic error, Run-time error '1004': Unable to get the Max property of the WorksheetFunction class.
Clicking the 'Debug' button takes me to the Cells(CurrentCol_I, 2) =... line.
Any ideas as to how this line should be written? Or if there are other mistakes in the code?
Thanks in advance.
Hi
how about
ryloSub aaa() For i = 2 To Cells(8, Columns.Count).End(xlToLeft).Column Cells(2, i).Value = WorksheetFunction.Max(Range(Cells(9, i), Cells(Rows.Count, i).End(xlUp))) Next i End Sub
Welcome to the forum.
One way:
The code considers the fact that the used range does not always include A1.Sub MAXVALUES() Dim r As Range Dim lCol As Integer Dim iCol As Integer Set r = Intersect(ActiveSheet.UsedRange, Rows("9:" & Rows.Count)) lCol = ActiveSheet.UsedRange.Columns.Count For iCol = 1 To lCol Cells(2, r.Columns(iCol).Column) = WorksheetFunction.Max(r.Columns(iCol)) Next iCol End Sub
Microsoft MVP - Excel
Entia non sunt multiplicanda sine necessitate
If there are no numeric values above row 9 then you could also use entire column references in the MAX.
The MAX function will only use the Intersect of the Used Range and the precedent range (unlike SUMPRODUCT / Arrays).
edit: just to be clear - I'm not saying you *should* ... the above is more to do with how MAX works (in terms of worrying about last row etc...)
Last edited by DonkeyOte; 10-15-2010 at 05:04 AM. Reason: typo
My Recommended Reading:
Volatility
Sumproduct & Arrays
Pivot Intro
Email from XL - VBA & Outlook VBA
Function Dictionary & Function Translations
Dynamic Named Ranges
My thought was that there might be values in row 2 from a previous invocation.If there are no numeric values above row 9 then you could also use entire column references in the MAX.
But on that topic, DO, do you have a list (or reference to) the functions that clamp to the used range?
Microsoft MVP - Excel
Entia non sunt multiplicanda sine necessitate
Unfortunately not... my belief is that this holds true for the majority of functions with the exception of SUMPRODUCT & Arrays and things like LOOKUP(2,1/...) & INDEX(...,0) etc...Originally Posted by shg
I've seen Charles Williams demo/test by comparing the calc. time of a given function using entire column & specific range precedents - and showing results to be the same (using his own precision tools of course).
This is one of the reasons I'm wary of advocating DNR's when specifically used to restrict range references (I know you like them for other reasons like visibility).
A lot of functions are so efficient the overhead in establishing the "used range" is not always necessary.
Last edited by DonkeyOte; 10-15-2010 at 11:26 AM. Reason: missing word
My Recommended Reading:
Volatility
Sumproduct & Arrays
Pivot Intro
Email from XL - VBA & Outlook VBA
Function Dictionary & Function Translations
Dynamic Named Ranges
DNR = Do Not Resuscitate, as in, Can this formula be saved?
Microsoft MVP - Excel
Entia non sunt multiplicanda sine necessitate
to be specific... Dynamic Named Ranges
there was a great (and I mean great) exchange a while back at MrExcel involving Charles W:
http://www.mrexcel.com/forum/showthread.php?t=371570
(do I get infracted for posting that link ?)
edit:
D'oh !Originally Posted by shg
Last edited by DonkeyOte; 10-15-2010 at 11:45 AM.
My Recommended Reading:
Volatility
Sumproduct & Arrays
Pivot Intro
Email from XL - VBA & Outlook VBA
Function Dictionary & Function Translations
Dynamic Named Ranges
Thanks for the linkm, that was interesting. It did not surprise me that Excel has no concept of 'used column' vs 'used range;' there's nothing in the object model to suggest otherwise.
I posted a link yesterday from there to here for an OP who wanted to post a file for me to look at. So far, I haven't been shot ...(do I get infracted for posting that link ?)
Microsoft MVP - Excel
Entia non sunt multiplicanda sine necessitate
I took the liberty of emailing Charles Williams regards "the function list" and he has kindly replied as follows:
Originally Posted by Charles Williams
My Recommended Reading:
Volatility
Sumproduct & Arrays
Pivot Intro
Email from XL - VBA & Outlook VBA
Function Dictionary & Function Translations
Dynamic Named Ranges
And if you want to take the usedrange per column into account you could use a UDF:Sub snb() sq = Cells(2, 1).Resize(, 3) For j = 1 To UBound(sq, 2) sq(1, j) = Application.Max(Cells(10, 1).Resize(5000).Offset(, j - 1)) Next Cells(2, 1).Resize(, 3) = sq End Sub
in A2: =max(snb(9,column()))
Function snb(r, c) snb = Cells(r, c).Resize(Cells(Rows.Count, c).End(xlUp).Row - (r - 1)) End Function
Last edited by snb; 10-16-2010 at 03:35 PM.
(Apologies for not coming back to this sooner...)
Thanks for all the replies and suggestions. Lots of good stuff and I've learnt much from it.
Here's what I tried (which works):
Cheers.Dim LASTCOL_I As Integer LASTCOL_I = ActiveSheet.UsedRange.Columns.Count Dim CurrentCol_I As Integer CurrentCol_I = 3 Dim CurrentCol_S As String CurrentCol_S = MultiLetter(CurrentCol_I) Do Until CurrentCol_I = LASTCOL_I + 1 Range(CurrentCol_S & "2").Select ActiveCell.FormulaR1C1 = "=MAX(R[7]C:R[4998]C)" CurrentCol_I = CurrentCol_I + 1 CurrentCol_S = MultiLetter(CurrentCol_I) Loop
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks