I've created an Excel Userform to facilitate the data entry of new lines into a contract register. I have a field that auto-generates a new unique contract number by looking for the largest number in the list of contract numbers (Column A) and then adds 1. This formula works perfectly:
Me.tbContractNumber = Application.WorksheetFunction.Max(Sheet1.UsedRange.Columns(1)) + 1
I now have to add an IF criteria to filter out any contract numbers LESS Than "2018000". I have worked out how to do this in a normal Excel workbook using MAXIFS but apparently MAXIFS is not an available function in VBA?
Can someone suggest an equivalent VBA code to the below Excel formula? Thanking you in advance!
=MAXIFS(A2:A500,A2:A500,"<2018000")+1
EDIT Our work computers run 2010 and won't allow me to add the MS Office 16.0 Object Library so MAXIFS function will not work. I can get the following array formula to work but I have never used an array formula in VBA. Could someone please suggest an equivalent VBA code to the below Excel formula? Thanking you in advance!
{=MAX(IF(A:A<2018000,A:A)) +1}
If you're looking for the largest number anyway, do you need to filter out anything lower than 2018000? If you have at least one entry equal to/higher than 2018000, your end result will be higher regardless of the other entries.
I'm sure there are more efficient ways of doing it, but if you are happy with:
Me.tbContractNumber = Application.WorksheetFunction.Max(Sheet1.UsedRange.Columns(1)) + 1
then try:
me.tbContractNumber = Application.WorksheetFunction.MaxIfs(Sheet1.UsedRange.Columns(1), Sheet1.UsedRange.Columns(1), ">" & 2018000) + 1
...but apparently MAXIFS is not an available function in VBA. In VBA it is not present, but if you add the Excel 16.0 Object Library (second on the screenshot) to your project, you would be able to access it as follows:
Application.WorksheetFunction.MaxIfs 'Only in Excel
Excel.WorksheetFunction.MaxIfs 'Any host of VBA - Excel, Access, Word
The library is added by default, if you work in Excel. Concerning "translation" the working formula from Excel to VBA, check this:
https://stackoverflow.com/a/49363501/5448626
I just learned the Evaluate function! So equivalent of the array formula I want to use converts in VBA to:
Me.tbContractNumber = Evaluate("=MAX(IF(" & "A:A" & "<2018000," & "A:A" & "))+1")
Related
For example:
I want it to become:
This clearly has to be done dynamically.
In Office 365 you could create the required result in a different column/sheet with this formula: =A1:A11&IF(COUNTIF(OFFSET(A1,,,SEQUENCE(COUNTA(A1:A11),),),A1:A11)-1=0,"","_"&COUNTIF(OFFSET(A1,,,SEQUENCE(COUNTA(A1:A11),),),A1:A11)-1)
Or using LET:
=LET(data,A1:A11,
countif,COUNTIF(OFFSET(data,,,SEQUENCE(COUNTA(data))),data)-1,
data&IF(countif=0,"","_"&countif))
If you want the data replaced with the amended data you need a VBA solution
I am using excel 2010 and do not have the GetNumeric function available.
I need to get the string from "A1:A200" and put just the numeric value in "B2:B200"
I have tried to use the "Sumproduct but not had much luck.
Thank you for taking the time to check out my question.
For an Excel formula you can use this:
=SUM(MID(0&A2,LARGE(INDEX(ISNUMBER(--MID(A2,ROW($1:$99),1))*ROW($1:$99),),ROW($1:$99))+1,1)*10^ROW($1:$99)/10)
I copied the formula from this website, which also provides other options for returning only a numeric value from a cell.
I have a python 3.7 script that has been developed using the OPENPYXL (v2.5.10) library to take data from a number of excel workbooks, to process that data and then to write to a separate excel workbook. The results workbook contains around 100 named ranges and numerous formula which all work as expected including automatically calculating when the workbook is opened in excel.
I am having trouble with one particular formula group which includes the AGGREGATE function. In this case the formula writes to the results workbook, to the correct cell and in the correct form. While other formulas show the resulting value on opening the workbook, this sequence of formulas only show a result if you select the cell, place the cursor in the formula bar (as if you are editing the formula) and then you push the enter/return key. No change or edit is made to the formula. Once you have done this the formula works as expected.
I have tested this on both the latest macOS and windows versions of excel and I get the same behaviour. I should add that trying the 'calculate now', CtrlShiftAltF9, and 'calculate sheet' options do not have any impact. The only time the formula calculates is if you use the enter/return key.
The code that writes the formula is:
activeSheet.cell(row, col).value = f"=IFERROR(INDEX({rngData}, AGGREGATE(15,3,({rng}={cellRef})/({rng}={cellRef})*ROW({rng}),{nth}),{colIndex}),\"\")"
which gives, for example, a correct result in the excel workbook cell as:
=IFERROR(INDEX(_monthAgedDebt_Data, AGGREGATE(15,3,(_monthAgedDebt_ProjectNumbers=$L$4)/(_monthAgedDebt_ProjectNumbers=$L$4)*ROW(_monthAgedDebt_ProjectNumbers),1),6),"")
So in summary:
the code works as it writes the correct formula to the correct cell and in the correct form
in excel the formula does not automatically calculate but only works if you edit the formula in the cell, make no changes, and push enter/return to exit the edit
Is it an issue with AGGREGATE producing an array result? I chose this form of formula principally because you do not need a CTL-SHIFT-ENTER to make it work. If you enter it directly into a cell in excel you can enter it as a normal formula.
I haven't been able to find help on stack overflow other than this one. However, the solution proposed here doesn't work either.
This question poses a similar issue but has no relevant responses.
This question may hold a clue but I don't seem to be able to make that work as well.
Any thoughts on how to fix this issue appreciated. I am not sure if it is an openpyxl issue or an excel issue and am not sure what else to test.
All - the final answer for completeness.
It turns out that the key to solving this issue lay with OPENPYXL and that the guidance provided in the answer by Charlie Clark to this
question
was correct. I had initially applied the solution incorrectly.
I changed the formula to:
activeSheet.cell(row, col).value = \
f"=IFERROR(INDEX({rngData}, _xlfn.AGGREGATE(15,3,({rng}={cellRef})/({rng}={cellRef})*ROW({rng}),{nth}),{colIndex}),\"\")"
by adding in the '_xlfn.' to the front of the AGGREGATE function statement.
The excel spreadsheet now works as expected without the need to edit the cell containing the formula.
I have a Excel (Office2010) range table as per following
using excel formulas (no VBA) how do i find
What subjects "Jane" has completed?
Who has done "Spanish"
i have tried few types of vlookup,hlookup index/match without having any luck
any help would be much appreciated.
Due to Office 2010 i cannot use TEXTJOIN function (as answered by #Louis Ries)
Thanks in Advance.
I was able to find a solution in Excel 2016, but after extensive research, I've found no way to select the data and eliminate values that don't match with formulas, and no VBA or add-ins. I'm quite interested in learning a solution for this that is compatible with previous versions of excel, but don't believe I'll find one anytime soon. My best suggestion is to obsolesce your version of Excel for 2016.
If you are using Excel 2016:
Note: I created a copy of the data and inserted it as a Table("Table1") with headers.
Enter this into a cell as an array formula(CTRL + SHIFT + ENTER).
It will retrieve all subjects that Jane has completed.
=TEXTJOIN("; ",1,REPT(Table1[Subject],1*(Table1[Jane]="x")))
Enter this into a cell as an array formula (CTRL + SHIFT + ENTER).
It will retrieve all headers where the row you desire has an x.
=TEXTJOIN("; ",1,REPT(Table1[#Headers],1*(A4:F4="x")))
If you select a row and create an alias(i.e. select A4:F4 and in name manger, alias it as Spanish), you can use this. (CTRL+SHIFT+ENTER)
=TEXTJOIN("; ",1,REPT(Table1[#Headers],1*(Spanish="x")))
we are looking to find the original? source code for SUMIFS to use in out excel sheet (for both 2003 and 2007. Here is why:
2003 doest support the SUMIFS method
When we do have SUMIFS we cannot utilize formulas "around" the columns (like YEAR())
For example, we want to calculate the ANSWERS that match the YEAR value of the date in cell A1 with the date values in range L:L. Now this doesnt work because we cant use YEAR(L:L) and hence we need to make another column M:M with the YEAR values from L:L
Thus we need the source to be able to upgrade the code further
=SUMIFS(ANSWERS;L:L;"="&YEAR(A1)) <= This works
=SUMIFS(ANSWERS;YEAR(L:L);"="&YEAR(A1)) <= This doesnt
Many thanks
With referenc to these questions:
Replacing SUMIFS in Excel 2003
VBA code for SUMIFS?
I doubt that you'll find the original code, which is, I imagine, C++ and part of the Excel internals. If that's correct, then it wouldn't help much, even if Microsoft gave it to you!
In general, I recommend against using =SUMIF(), =SUMIFS() and other functions that take a string to define the condition for testing: apart from anything else, I'm concerned that they're going to be slow, since my best guess is that internally they construct a string for evaluation for each value. In XL2007 (all I have available right now) at least, this turns out not to be necessarily true (see comments below).
I'm generally much happier with array functions. This, for example, should work in both Excel 2003 & 2007:
=SUMPRODUCT(--(YEAR(L:L)=YEAR(A1)),ANSWERS)
This gets the same answer:
{=SUM(IF(YEAR(L:L)=YEAR(A1),ANSWERS,0))}
In the latter case, you'd enter the formula without the curly braces ({ & }) and confirm it using Control+Shift+Enter to tell Excel it's an array formula.
In the first example, we build a list of boolean results with YEAR(L:L)=YEAR(A1) and convert it into an array of 1s and 0s using the double-negative. Then SUMPRODUCT takes care of the rest. This version requires that ANSWERS has the same dimension as L:L, i.e. it should be the entire column (or the range in L should be constrained in size).
In the second, Excel will run through each entry in L:L. If its year matches that in A1 then the corresponding ANSWERS value will be used, otherwise zero. This formula seems to be more tolerant of dimension differences but I'd still be careful.