I want function convert from xy to cells - excel

How do I return a result from a function?
For example:vba: i want function
Function xy2cell(i, f)
xy2cell = "=" & "?????????????????????????????"
End Function
Sub aaa_main()
ActiveSheet.Cells.Clear
f = "5^4*x-2^4*y-1"
For i = 1 To 2
Cells(i, 3) = xy2cell(i, f)
Next
End Sub
'I want
'Cells(1, 3) = "=5^4*" & Cells(1, 1).Address & "-2^4*" & Cells(1, 2).Address & "-1"
'Cells(2, 3) = "=5^4*" & Cells(2, 1).Address & "-2^4*" & Cells(2, 2).Address & "-1"
(20220328)
original
Japanese below ↓↓↓↓↓↓-------------------------------------------
2022 Mathematics 1A Q4 < The Common Test for University Admissions is a common entrance examination for Japanese universities
https://cdn.mainichi.jp/item/jp/etc/kyotsu-2022/pdf/MTAP.pdf#page=20
I try (vba & vba solver)
https://qiita.com/mrrclb48z/items/af08059157cfbce8f0fe
Japanese up ↑↑↑↑↑-------------------------------------------

A simpler approach is to use the formual2R1C1 property of a range. This allows you to specify a formula using notation that refers to cells as offsets from the destination cell. This way, a single expression can be used to create different formulas in each target cell of the range.
Sub aaa_main_2()
Dim f As String
f = "=5^4*x-2^4*y-1"
f = Replace(f, "x", "RC[-2]")
f = Replace(f, "y", "RC[-1]")
ActiveSheet.Cells.Clear
Range("C1:C2").Formula2R1C1 = f
End Sub
or, more directly
Sub aaa_main_3()
ActiveSheet.Cells.Clear
Range("C1:C2").Formula2R1C1 = "=5^4*RC[-2]-2^4*RC[-1]-1"
End Sub

It seems unusual to clear all the cells from the active sheet, as this would remove any inputs on which the function would operate. Nonetheless, here is your code converted to do as you ask. I've added Dim statements to declare the variables your code uses.
Function xy2cell(i As Long, f As String)
Dim formula As String
formula = Replace(f, "x", Cells(i, 1).Address(False, False))
formula = Replace(formula, "y", Cells(i, 2).Address(False, False))
xy2cell = "=" & formula
End Function
Sub aaa_main()
Dim f As String
Dim i As Long
ActiveSheet.Cells.Clear
f = "5^4*x-2^4*y-1"
For i = 1 To 2
Cells(i, 3).Formula = xy2cell(i, f)
Next
End Sub
This code uses the "replace" function to find "x" in your formula string (f) and replace it with the appropriate cell reference. The result is stored in a variable named "formula" which is then used as the input to replace y with the appropriate cell reference.
However, there is a much simpler approach using the formula2R1C1 property. I'll post a separate solution on that technique.

Related

How to calculate the sum of a textbox value and print it to a cell?

How do I calculate the value of a text box and print it to a cell in Microsoft Excel VBA?
For example: I enter 2*2 into my textbox, and I want it to print 4 to a cell.
the textbox is in a userform this is what i have so far, although it works it doesn't look nice. I'm new to excel so help is appreciated.
Private Sub Submit_Click()
Dim str As String
Dim bracket As String
lastrow = Cells(Rows.Count, 1).End(xlUp).Row + 1
str = "=SUM("
bracket = ")"
Application.ScreenUpdating = False
Sheets("Value").Activate
Cells(lastrow, 1) = str & txtbox.Value & bracket
Application.ScreenUpdating = True
Fully Qualify your Objects.
Currently, you are writing Cells(lastrow, 1) = str & txtbox.Value & bracket
Excel is implictly treating this as ActiveSheet.Cells(lastrow, 1).Value = str & txtbox.Value & bracket - because you only provide half the information, it has to guess. It assumes you want the ActiveSheet, and it assumes you want to change the Value. But, you don't.
To put a Formula into a Cell in VBA, don't use Value - use Formula, like so: ActiveSheet.Cells(lastrow,1).Formula = str & txtbox.Value & bracket
Alternatively, if you want the Value, but not the Formula, then there are 2 methods. Either convert the result, like so:
With ActiveSheet.Cells(lastrow, 1)
.Formula = str & txtbox.Value & bracket
.Calculate
.Value = .Value
End With
Or use the Application.Evaluate method:
ActiveSheet.Cells(lastrow, 1).Value = EVALUATE(str & txtbox.Value & bracket)
Private Sub Submit_Click()
With Sheets("Value")
.Cells(Rows.Count, 1).End(xlUp).offset(1 ,0).formula = "=" & me.txtbox
End With
End Sub
I assume that the textbox is called txtbox and that the routine is being run from a button on the same userform

Compare all column values against individual cells in Excel

I'd like to find if any row in Column C matches any cells in Column A or B and print out 'yes' or 'no' in an adjacent cell if it does match. The match might not be exact, because an ID may be written as '12401' but the match in the column may be like 'cf[12401]', with the ID enclosed in brackets.
This is an example of what I might find in the table. The values in A and B columns originally came from another table but I'm trying to find all instances of where they might exist in the third column.
Excel Example:
If possible, I'd like to list the values themselves that matched in the column. But that part would be a nice extra while the other part is more important because there are around 6000 values in the middle column so it would take days by hand.
I've tried different things like this:
=IF(COUNTIF(C2,"*" & A6 & "*" ), "Yes", "No")
or
=IF(COUNTIF(C2,"*" & Length & "*" ), "Yes", "No")
these work for individual words or cells, but trying to check all the values in that column against the cell will return no. I've tried variations of SUMPRODUCT and others that I've found, but haven't been able to get something that works for multiple values.
Is there some function in Excel that will allow me to do this? Or maybe a way in VBA?
Here is some UDF you could use.
Dim MyArr As Variant, X As Double, LR As Double
Option Explicit
Public Function MatchID(RNG As Range) As String
With ActiveWorkbook.Sheets(RNG.Parent.Name)
LR = .Cells(Rows.Count, 1).End(xlUp).Row
MyArr = Application.Transpose(.Range(.Cells(2, 1), .Cells(LR, 1)))
For X = LBound(MyArr) To UBound(MyArr)
If InStr(1, RNG.Value, MyArr(X), vbTextCompare) > 0 Then
If MatchID = "" Then
MatchID = MyArr(X)
Else
MatchID = MatchID & ", " & MyArr(X)
End If
End If
Next X
End With
End Function
Public Function MatchCFNAME(RNG As Range) As String
With ActiveWorkbook.Sheets(RNG.Parent.Name)
LR = .Cells(Rows.Count, 1).End(xlUp).Row
MyArr = Application.Transpose(.Range(.Cells(2, 2), .Cells(LR, 2)))
For X = LBound(MyArr) To UBound(MyArr)
If InStr(1, RNG.Value, MyArr(X), vbTextCompare) > 0 Then
If MatchCFNAME = "" Then
MatchCFNAME = MyArr(X)
Else
MatchCFNAME = MatchCFNAME & ", " & MyArr(X)
End If
End If
Next X
End With
End Function
In D2 Ijust used =IF(F2<>"","YES","") and dragged it sideways and down.

Adding freshly created formula into new module

I've just created a brand new macro. Took function down below from internet (all credits goes to trumpexcel.com), code down below
Function CONCATENATEMULTIPLE(Ref As Range, Separator As String) As String
Dim Cell As Range
Dim Result As String
For Each Cell In Ref
Result = Result & Cell.Value & Separator
Next Cell
CONCATENATEMULTIPLE = Left(Result, Len(Result) - 1)
End Function
Then I proceed to extract data from various columns and into the one (my table is 20 rows x 10 columns)
Sub conact_data()
Dim i As Integer
For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row
Cells(i, "M").Value = Cells(i, "A").Value & " " & _
Cells(i, "B").Value & " / " & Cells(i, "D").Value & "; "
Next i
End Sub
Thanks to that I've got combined data from column A, B and D, so its 20 rows. All I want to do now is to concatenate data from M2:M21 using CONCATENATEMULTIPLE function therefore I try various approach (I want this huge line in P2 cell) like :
Cells(2, 16).Value = CONCATENATEMULTIPLE (M2:M21, " ")
or
Range("P2") = "CONCATENATEMULTIPLE (M2:M21, " ")"
I don't really know how to apply that
Secondly, I'd like withdraw the Cells(i, "B").Value as percentage. Can I do that in one line like Cells(i, "B").NumberFormat="0.00%".Value (which is not working for me obviously) else I need to copy column B into another column with number format and then combine the new column, properly formatted instead of column B?
Thanks in advance
Percent format: Range("B" & i).NumberFormat = "0.00%"
CONCATENATEMULTIPLE
In VBA, CHR(32) = " "
In Excel, CHAR(32) = " "
With that being said...
'Value
Range("P2").Value = CONCATENATEMULTIPLE(Range("M2:M21"), CHR(32))
'Formula
Range("P2").Formula = "=CONCATENATEMULTIPLE(M2:M21, CHAR(32))"
You should really qualify all of your ranges with a worksheet
Say your workbook has 10 sheets. When you say Range("P2"), how do we (VBE) know what sheet you mean? Objects need to be properly qualified. Sometimes this is not a huge issue, but when you are working across multiple sheets, not qualifying ranges can lead to some unexpected results.
You can qualify with a worksheet a few ways.
Directly: ThisWorkbook.Sheets("Sheet1").Range("P2").Copy
Or use a variable like so
Dim ws as Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
ws.Range("P2").Copy
Now there is no room for ambiguity (potential errors) as to the exact location of Range("P2")
First of all, remove your ConcatenateMultiple() code, and instead use Excel worksheet function CONCAT(), which takes a range and a delimiter as parameters.
Here is how you can handle the percentage issue and supply a default for non-numeric items. I've also cleaned up the way you reference your data range.
Sub concat_data()
Dim rngRow As Range, vResult As Variant
Const DEFAULT = 0 'Can also be set to a text value, eg. "Missing"
For Each rngRow In [A2].CurrentRegion.Rows
If IsNumeric(rngRow.Cells(, 4)) Then vResult = rngRow.Cells(, 4) * 100 & "%" Else vResult = DEFAULT
Range("M" & rngRow.Row) = rngRow.Cells(, 1) & rngRow.Cells(, 2) & "/" & vResult & ";"
Next
[M2].End(xlDown).Offset(1).Formula = "=CONCAT(M2:M" & [M2].End(xlDown).Row & ",TRUE,"" "")"
End Sub
I'm not a fan of hard-coding range references, like the [A2] or Range("M"), but will leave that for another time.

Using Dictionary (hashing) in VBA

I have an excel workbook with multiple sheets.
I have to get counts of certain entries by using filters(i'm searching text instead of using filters here)
The "Main" sheet is where the count is updated. The strings are searched from other sheets in the workbook
The cells where the count should be updated varies.
The search criteria,keyword,sheet,range, etc is given in the sample code which I have posted.
Example from code:
In Cell, AE43, the count is updated only when the sheet "TT" meets the criteria mentioned.
So, similarly I'll have to use the same kind of code 30+ times for different cells to get the data.
So instead of typing the code for similar search, I want to know whether we can use "Dictionary" function (hashing in other languages) here, so that a cell can be updated automatically if it meets the criteria.
Sub WBR()
Dim wf As WorksheetFunction
Set wf = Application.WorksheetFunction
With ActiveWorkbook.Worksheets("TT") 'no of tickets processed - summary
[AE43] = wf.CountIfs(.Range("I:I"), "<>Duplicate TT", _
.Range("G:G"), "<>Not Tested", _
.Range("U:U"), "Item")
End With
With ActiveWorkbook.Worksheets("TT") 'not tested tickets - summary
[AE44] = wf.CountIfs(.Range("G:G"), "Not Tested")
End With
With ActiveWorkbook.Worksheets("TT") 'Tickets moved back- outdated OS and App Versions - summary
[AE45] = wf.CountIf(.Range("I:I"), "Outdated App Version") + wf.CountIf(.Range("I:I"), "Outdated OS")
End With
Here's a basic example which should get you started.
Sub showing how to call the code:
Sub Tester()
With ThisWorkbook.Sheets("Main")
.Range("A1") = GetCount("TT", False, "A:A", "Blue")
.Range("A2") = GetCount("TT", False, "A:A", "Blue", "C:C", "Red")
.Range("A3") = GetCount("TT", True, "A:A", "Blue", "C:C", "Red")
End With
End Sub
Generalized version of your use cases:
'If addValues is True and there are >1 set of criteria then
' sum up a bunch of COUNTIF(), else use COUNTIFS() so all
' criteria are applied at the same time
Function GetCount(shtName As String, addValues As Boolean, _
ParamArray crit()) As Long
Dim sht As Worksheet, f As String, num As Long, i As Long
Set sht = ThisWorkbook.Sheets(shtName)'<< counting things on this sheet
num = UBound(crit)
If num = 1 Or addValues Then
f = "COUNTIF(" & crit(0) & ",""" & crit(1) & """)"
End If
If num > 1 Then
If addValues Then
'already got the first pair: add the rest
For i = 2 To num Step 2
f = f & " + COUNTIF(" & crit(i) & ",""" & crit(i + 1) & """)"
Next i
Else
f = "COUNTIFS("
For i = 0 To num Step 2
f = f & crit(i) & ",""" & crit(i + 1) & """"
If i <> num - 1 Then f = f & ","
Next i
f = f & ")"
End If
End If
If f <> "" Then
Debug.Print f
GetCount = sht.Evaluate(f) '<<do not use Application.Evaluate here
Else
GetCount = -1 '<< something went wrong...
End If
End Function
Debug output:
COUNTIF(A:A,"Blue")
COUNTIFS(A:A,"Blue",C:C,"Red")
COUNTIF(A:A,"Blue") + COUNTIF(C:C,"Red")
Probably could use some error-handling and if there are other use cases you'll need to add those in.

Write several values in one string

I am new to both VBA and stackoverflow. So please be patient ;).
I searched for a solution but could not find it.
My problem is as follows:
I have a column (A) with names and then a column (B) where some cells contain an "X" and others do not. I want to know which names have an "X" besides them.
Example:
I want now a string as a result, in one cell.
In this example:
Noah;Jacob;Elijah;Jayden
I got not very far.
For r = 1 To 20
If Cells(r, 2) = "X" Then A = Cells(r, 1) Else
Next
Then "A" is "Noah" and I can write it in a cell, but I want it to find all values and then write them combined, preferable seperated by ; in a cell.
Does anyone have any idea?
Create a string variable, then append your results to that variable based on "X" being in column B. Here's an example of how you could do it:
Sub Foo()
Dim i As Integer
Dim result As String
For i = 1 To 20
If UCase(Cells(i, 2).Value) = "X" Then
result = result & Cells(i, 1).Value & ";"
End If
Next
'// output the result to C1
Range("C1").Value = Left$(result, Len(result) - 1)
End Sub
Excel's native worksheet formulas do not handle concatenating an unknown number of strings together and compensating for the maximum number possible can get messy. A User Defined Function¹ (aka UDF) takes advantage of VBA's ability to process loops through a large number of rows while making numerical or string comparisons 'on-the-fly'.
build_List UDF
Function build_List(rNAMs As Range, rEXs As Range, vEX As Variant, _
Optional delim As String = ";", _
Optional bCS As Boolean = False)
Dim str As String, rw As Long, cl As Long
With rNAMs.Parent
Set rNAMs = Intersect(.UsedRange, rNAMs)
Set rEXs = .Cells(rEXs.Rows(1).Row, rEXs.Columns(1).Column). _
Resize(rNAMs.Rows.Count, rNAMs.Columns.Count)
End With
With rNAMs
For rw = .Rows(1).Row To .Rows(.Rows.Count).Row
For cl = .Columns(1).Row To .Columns(.Columns.Count).Row
If (.Cells(rw, cl).Offset(0, rEXs.Column + (cl - 1) - cl) = vEX And bCS) Or _
(LCase(.Cells(rw, cl).Offset(0, rEXs.Column + (cl - 1) - cl)) = LCase(vEX)) Then _
str = str & .Cells(rw, cl).Value & delim
Next cl
Next rw
End With
build_List = Left(str, Len(str) - Len(delim))
End Function
In D7 (as per image below) as,
=build_List(A:A, B:B, "x")
                               Applying the build_Lists UDf to your sample data
¹ A User Defined Function (aka UDF) is placed into a standard module code sheet. Tap Alt+F11 and when the VBE opens, immediately use the pull-down menus to Insert ► Module (Alt+I,M). Paste the function code into the new module code sheet titled something like Book1 - Module1 (Code). Tap Alt+Q to return to your worksheet(s).
Mate Juhasz answered the question very nice and simple, but now the answer dissapeared.
Mate wrote:
For r = 1 To 20
If Cells(r, 2) = "X" Then A = A & "; " & Cells(r, 1) Else
Next
And for me that solved it perfectly. Now "A" is a string as I wanted. Thank you so much!

Resources