I'm trying to convert an excel array to VBA. Any help would be appreciated:
{=IFERROR((MATCH('Surgery'!D10&'Surgery'!D11,'NCCI'!A1:A263469&'NCCI'!B1:B263469,0)),"")}
The Surgery worksheet is where the user inputs a list of codes and the NCCI worksheet is where the above array searches to find a match. It uses the two codes entered by the user to search in two columns on the NCCI worksheet to try and find where two codes are in the same row and returns the row number.
Unlike some other array formulas, this one does work with Application.Evaluate, it only needs to "double up" the double-quotes inside.
Dim v
v = Application.Evaluate("=IFERROR(MATCH(J2&K2,A1:A4&B1:B4,0), """")")
Debug.Print v
Related
I'm struggling with VBA and couldn't find a solution on internet.
This is what I'm trying to do.
I have an excel file with two sheets
First sheet is an extract from a Database (with many columns, an particulary one called "country"). It is formated as a ListObject
Second sheet is a Calculator that is counting the number of occurence of every country in the other sheet. It is also formated as a list object
For Example at the end I'll get:
France: 10
USA: 25
Italia: 30
I found how to calculate this using the Application.WorksheetFunction.CountIf function.
Now my question is: Is it possible to write the formula in the cell, instead of writing the result ?
The objectif is to generate a sheet filled with formulas, so that when I change things in the Database sheet, then it will automatically recalculate my results.
This is my current code: It works, but I'd like to write a formula in the cell, instead of the result.
It there an easyway to do this ?
Thanks a lof for your help !
Regards,
J.
Dim i As Long
Dim CountryName As Variant
Dim KPI_LO As ListObject
Dim REVIEWEDDATA_LO As ListObject
'This is the list object with the database information
Set REVIEWEDDATA_LO = Worksheets(REVIEWEDDATA_SHEET_NAME).ListObjects(REVIEWEDDATA_LISTOBJECT_NAME)
'This is the list object where I'll store my results
Set KPI_LO = Worksheets(WASPKPI_SHEET_NAME).ListObjects(WASPKPI_LISTOBJECT_NAME)
'loop through each country column in the result sheet
For i = LBound(GetCountriesList) To UBound(GetCountriesList)
'Get the name of the first country to find
CountryName = GetCountriesList(i)
'Count the number of occurence of this country in the column called COL_COUNTRY in the revieweddata List Object (in my database sheet).
'This is what I'm trying to replace. I want to write a formula that do this calculation in the cell, instead of the result.
KPI_LO.ListColumns(CountryName).DataBodyRange.Rows(1) = Application.WorksheetFunction.CountIf(REVIEWEDDATA_LO.ListColumns(COL_COUNTRY).DataBodyRange, CountryName)
Next i
if you want to see the formula in a cell, then you can create a function and then just call that and pass through your values.
For example, create a module:
Function fn_Multiply(x As Double, y As Double) As Double
Dim z As Double
z = x * y
fn_Multiply = z
End Function
And use it in excel as a formula like this:
=fn_Multiply(A2,B2)
enter image description here
I am creating an excel object from a vb.net listview table simply by creating an array of F(x,y), creating a range and putting the values from the array in the range as follows.
shXL.Range(Startcell,AEndCell).Value = F
However some of the fields are numeric and I want them to be formatted to two decimal places and EXCEL to recognize them as decimals
What I end up with in the excel worksheet is many green triangles telling me they are text fields.
How do I convert a range withing the sheet say A5,I20 to be formated as decimals.
I tried: (x,y).numberformat = "00.00" which works to format to 2dp but still treats the cells as text.
Furthermore, is it possible to Excel Sum a range? How is the possible?
Your help is appreciated!
shXL.Range(Startcell,AEndCell).Value = F
'// Loop over same range and convert to decimal
For Each cell In shXl.Range(Startcell,AEndCell)
With cell
.Value = CDec(.Value)
End With
Next
Furthermore, is it possible to Excel Sum a range? How is the possible?
I don't think Excel would have got very far as a spreadsheet product if it couldn't sum a range!
Assuming you want to do this in vb.net you need to use the instance of the application. I'll assume in your code it's XL
mySumValue = XL.WorksheetFunction.Sum(shXL.Range(Startcell,AEndCell))
I'm trying to set a macro, that will compare multiple lists, create a cross-table with unique values and display how many times the value is present in each list.
I'm doing OK, with one exception. When using Countif(s) formula =COUNTIFS(Source!$A$2:$A$5;[#Values]), it internaly converts "Text numbers" (e.g. 001, 00000002) into Numbers (e.g. 1, 2). I would like to avoid this behaviour and search for EXACTLY the same value, without converting.
Example data:
List1 List2
1 0001
0001
2
00000002
What I'm getting right now (WRONG):
What I want to get (EXPECTED):
My question:
How can I count EXACTLY the values in the list, without internaly converting "Text numbers" to Numbers?
This array formula could be suitable for you:
=MIN(SUMPRODUCT(IF(LEN($A$2:$A$5)=LEN(Table1[#Values]),1,0)),SUMPRODUCT(IF($A$2:$A$5=Table1[#Values],1,0)))
Put and CTRL+SHIFT+ENTER. In Table1[#Values], Table1 is your table name.
I solved the problem with simple UDF.
Function countifsExact(criteria_range As Range, criteria As String) As Long
Dim cell As Range
For Each cell In criteria_range
If cell = criteria Then
countifsExact = countifsExact + 1
End If
Next cell
End Function
EDIT1:
I made another version of the UDF using some of the advice given in Writing efficient VBA UDFs (Part 1) by Charles Williams and in Writing efficient VBA UDFs (Part 2) by Charles Williams.
Mainly:
Storing the criteria_range once in a Variant variable avoiding a large overhead each time a VBA program transfers data from an Excel cell to a VBA variable
Using Range.Value2 property, instead of Range.Value
Using excel MATCH function to get a starting point in the sorted range, with exit on value change.
EDIT2:
Yet a much better solution is to use the SUMPRODUCT formula as such:
=SUMPRODUCT(--(EXACT(Source!$A$2:$A$5;[#Values])))
I'm messing with a spreadsheet containing postal addresses that have been inserted in the cells' comments
Each comment contain an address composed of a variable number of lines (damn UK addresses, they can have up to 7 lines!) in the following format:
Line1,
Line2,
Line3,
[...],
State
With my poor skills, I've managed to extract the comment with a VBA script, obtaining the following string on a single cell:
Line1,Line2,Line3,[...],State
At this point each string between commas must be extracted to its own cell.
I've managed to extract the 1st 3 lines with the following formulas:
For Line1:
=LEFT(A8;(SEARCH(",";A8))-1)
For Line2:
=MID(A8; SEARCH(",";A8)+1; SEARCH(","; A8; SEARCH(","; A8)+1)-SEARCH(",";A8)-1)
For Line3:
=MID(A8; SEARCH(",";A8;SEARCH(",";A8;SEARCH(",";A8;SEARCH(",";A8)))+1)+1;SEARCH(","; A8; SEARCH(","; A8;SEARCH(",";A8)+1)+1)-SEARCH(",";A8;SEARCH(",";A8)+1)-1)
From this point I start to get overflow errors from my brain... I probably need some days of sleep.
Can anybody help me to get to "line6", and finally suggest me how to pull out the "State line" which ends without comma?
I thought I could pull out the "State" line with =RIGHT(",";SEARCH(",";A8)-1) but I'm obviously doing something wrong because that pulls out a comma instead of a string.
I guess I could do everything with a VBA script, but I'm not that skilled yet :(
With comma separated data in A1, in B1 enter:
=TRIM(MID(SUBSTITUTE($A1,",",REPT(" ",999)),COLUMNS($A:A)*999-998,999))
and copy across. For example:
Note:
Why not use TextToColumns ?
The row of formulas re-calculates automatically if A1 changes.
The row of formulas will work even if A1, itself, contains a formula.
If you are wanting to do this programmatically instead of using a built-in, check out the split function for chopping up your comma separated string. It will split up your input string into an array. Then you can do whatever you like with the array.
Dim Names() As String
Names() = Split(inputValue, ",")
For i = 0 To UBound(Names)
' do what you want with each piece
Next
Gary's Student's answer is great for using the built-in functions.
If you want a VBA solution:
Sub spitString()
Dim sourceRange As Range
Dim stringArr() As String
Dim i As Integer
Set sourceRange = ActiveSheet.Range("A1")
stringArr = Split(sourceRange.Value, ",")
For i = LBound(stringArr) To UBound(stringArr)
sourceRange.Offset(0, i + 1).Value = stringArr(i)
Next i
End Sub
You could avoid adding comments: Are you aware that users can add line breaks inside a cell by pressing ALT+RETURN?
If having high rows d is a problem and you don't like that formatting, an alternative approach might be to write a simple bit of code that changes the height of the current row when a user clicks in a certain range. It would , make other rows less high. Perhaps.
Just a thought. It has benefits keeping it simple.
Harvey.
I'm new to Excel and the journey has been good so far, but I haven't been able to resolve this particular issue by myself. I'm dealing with a table as under:
Essentially, I'm looking to refer to the array of tags in columns from B3:E6, and do the following:
Create a "Unique Tags" column: Create a unique list of "tags" in column H by removing duplicates.
Create a "Maximum Marks" column: Look for each of the unique tags in the array in each row, and return the marks from the marks column in the same row. If the tag appears in multiple rows. the sum of the corresponding marks in these multiple rows should be returned in the maximum marks column in column I. For example, 'EASY' appears in E3 as well as E5. Thus in the 'Unique Tags' List 'EASY' should correspond to Maximum Marks = 4 (2+2).
I could do this manually using formulas such as SUMIF, but I'm looking for a way to automate it since I might have to do this operation for a similar dataset with additional rows & columns. I'm open to VBA solutions as well but would prefer some sort of formula.
I hope I've explained it well enough! Thanks and looking forward to your inputs.
One way to do this is create a function that returns the array of your unique cells and then multiplies them all by matches in your Marks column.
Create the unique cells with this array function. Note this function uses the Dictionary object. In the VB Editor, go to Tools > References, and make sure Microsoft Scripting Runtime is selected.
Public Function UniqueValues(aRange As Range)
Dim DictValues As New Dictionary
Dim cll As Variant
Dim aryResults() As String
For Each cll In aRange
If Not DictValues.Exists(cll.Value) Then DictValues.Add cll.Value, "":
Next
UniqueValues = DictValues.Keys
Set DictValues = Nothing
End Function
Enter in cell H3 and press CTRL SHIFT RETURN (as it's an array function)
=TRANSPOSE(uniquevalues(B3:E6))
and drag down to H15 or beyond
We have to use TRANSPOSE as the array comes out in a row from the function.
Next we need to find the matching cells and multiply. Here in C15 enter the formula below
=INDEX(SUM((($B$3:$E$6=H3)*1)*$F$3:$F$6),1)
Drag this down to H15.