converted excel formal to DAX - dax

please anyone can help to convert this formal to Dax
=IF(COUNTIFS(D:D,D2,L:L,"Y")>1,"Only 1 Y contact","OK")
It is looking to see if there is more than one Y in a column (L:L) per patient id. (D:D)

I don't know any DAX function that would count the number of occurrences of a sub string in a string, but one can use SUBSTITUTE() to remove each occurrences of a sub string in the string, then compute the length LEN() difference with original string :
IF(
LEN('Table'[Column])-
LEN(
SUBSTITUTE(
'Table'[Column],
"Y",
"" )
) > 1,
"Only 1 Y contact",
"OK")

Related

Power Query in Excel and pattern recognition

As Power Query does not provide support for RegEx how can I extract a number of 8 digits from a string.
The number can appear anywhere in the string.
I have tried to use M but didn't find any complete solution. I also tried the option "Column From Examples" but the complexity of the cases does not let me have a reliable result either.
I googled it but it seems there are no examples suitable for PowerQuery/M
abc123456 -->null
abc12345678 -->12345678
abc 12345678 -->12345678
abc 12345678aaaa -->12345678
abc 1111 ddd12345678aaaa 3467-->12345678
abc 1111 ddd123456aaaa 3467-->null
etc...
EDIT
I have added the following code as suggested by Alexis Olson
= Table.AddColumn(
Sheet1_Sheet,
"PatternMatched",
(r) =>
List.First(
List.Select(
List.Transform(
{0..Text.Length(r[String]) - 8},
each Text.Range(r[String], _, 8)
),
each _ = Text.Select(_, {"0".."9"})
)
)
)
the code differs only for Sheet1_Sheet instead of #"Previous Step" because this is the field holding the data but I get the following error message "Expression.Error: The field 'String' of the record wasn't found. Details: Column1=abc123456" What am I doing wrong ?
EDIT2
I have found the error in my formula. Here the correct one
Table.AddColumn(
#"Renamed Columns",
"PatternMatched",
(r) =>
List.First(
List.Select(
List.Transform(
{0..Text.Length(r[Column]) - 8},
each Text.Range(r[Column], _, 8)
),
each _ = Text.Select(_, {"0".."9"})
)
)
)
I had simply to replace from Alexis Olson's answer:
#"Previous Step" with #"Renamed Columns" because that is the previous step name in the "Applied Steps" section of the "Query Settings" in PQ
r[String] with r[Column] because "Column" is the name of the
column containing the data I want to find the pattern in my PQ
It's not simple, but you could add a custom column that does this:
Table.AddColumn(
#"Previous Step",
"PatternMatched",
(r) =>
List.First(
List.Select(
List.Transform(
{0..Text.Length(r[String]) - 8},
each Text.Range(r[String], _, 8)
),
each _ = Text.Select(_, {"0".."9"})
)
)
)
Let's take a look at what's happening here with the example r[String] = abc12345678.
Since Text.Length(r[String]) = 11, we can look at substring ranges of length 8 starting at index 0 through index 11 - 8 = 3.
So List.Transform({0,1,2,3}, each Text.Range("abc12345678", _, 8)) transforms the list {0,1,2,3} into a list of 8-long substring ranges: {"abc12345", "bc123456", "c1234567", "12345678"}.
Now for each of these substrings, check if it consists of only digits by comparing each string to a version of itself containing only digits using Text.Select(_, {"0".."9"}) to strip all but the digit characters. Then List.Select each substring where this condition is true.
The result is a list of substrings that are a length of 8 and contain only digits (empty if none exist). Use List.First to return the first string from this list.

How to fetch text from dynamically changing string

Every day I am receiving values as given below, since to automate I want fetch last part of the string from a text. For example, from the following
a) 999999000045090
b) 9990090105
c) 9999010000
d) 990000660000
from the above I need to fetch actual values in the right as given here
a) 45090
b) 90105
c) 10000
d) 660000
since the length is varying and not fixed I need help to resolve
You can use a regular expression:
Dim inputString, regularExpression, outputString
inputString = "999999000045090"
Set regularExpression = New Regexp
regularExpression.Pattern = "^9+0+"
outputString = regularExpression.Replace(inputString, "")
^ will match the start of the string, 9+ will match 1 or more nines and 0+ will match 1 or more zeroes.
Which means that, in this example, 9999990000 will be replaced by an empty string, and that outputString will be 45090.
Disclaimer: not tested. I am not familiar with VBScript.

Usage of + operator in differents situations in vbscript

What is the Value of the below in vbscript
1)x=1+"1"
2)x="1"+"1"
3)x=1+"mulla"
Note:In the all above three cases I am using first variable as either string or integer and second on as always as string.
Case 1:Acting as a numeric and auto conversion to numeric during operation
enter code here
y=inputbox("Enter a numeric value","") Rem I am using 1 as input
x=1
msgbox x+y Rem value is 2
msgbox x*y Rem value is 1
Case 2:Acting as a String and no conversion to numeric during operation it fails
enter code here
y=inputbox("Enter a numeric value","") Rem I am using 1 as input
x=1
if y= x then
msgbox "pass"
else
msgbox "fail"
end if
Case 3:Acting as a String and explicit conversion to numeric during operation it passes
enter code here
y=inputbox("Enter a numeric value","") Rem I am using 1 as input
x=1
if Cint(y) = x then
msgbox "pass"
else
msgbox "fail"
end if
I need a logic reason for the different behaviors. but in other language it is straight forward and will work as expected
Reference: Addition Operator (+) (VBScript)
Although you can also use the + operator to concatenate two character strings, you should use the & operator for concatenation to eliminate ambiguity. When you use the + operator, you may not be able to determine whether addition or string concatenation will occur.
The type of the expressions determines the behavior of the + operator in the following way:
If Both expressions are numeric then the result is the addition of both numbers.
If Both expressions are strings then the result is the concatenation of both strings.
If One expression is numeric and the other is a string then an Error: type mismatch will be thrown.
When working with mixed data types it is best to cast your variables into a common data type using a Type Conversion Function.
I agree with most of what #thomas-inzina has said but the OP has asked for a more detailed explanation so here goes.
As #thomas-inzina point's out using + is dangerous when working with strings and can lead to ambiguity depending on how you combine different values.
VBScript is a scripting language and unlike it's big brothers (VB, VBA and VB.Net) it's typeless only (some debate about VB and VBA also being able to be typeless but that's another topic entirely) which means it uses one data type known as Variant. Variant can infer other data types such as Integer, String, DateTime etc which is where the ambiguity can arise.
This means that you can get some unexpected behaviour when using + instead of & as + is not only a concatenation operator when being used with strings but also a addition operator when working with numeric data types.
Dim x: x = 1
Dim y: y = "1"
WScript.Echo x + y
Output:
2
Dim x: x = "1"
Dim y: y = "1"
WScript.Echo x + y
Output:
11
Dim x: x = 1
Dim y: y = 1
WScript.Echo x + y
Output:
2
Dim x: x = 1
Dim y: y = "a"
WScript.Echo x + y
Output:
Microsoft VBScript runtime error (4, 5) : Type mismatch: '[string: "a"]'

How to calculate number of occurrences

Can someone show me how to make a number occurrences application in Visual Basic 2008? The program is supposed to prompt the user for a number and then it counts the occurrences of each number (0-9) in the user number.
For example, a number of 122378 would print out:
0=0, 1=1, 2=2, 3=1, 4=0, 5=0, 6=0, 7=1, 8=1, 9=0,
It says to treat the number like a string, and the answer should be displayed in a listbox.
There are other ways to do it but so you understand - do this:
'prepare placeholder
dim dict as New Dictionary(of String, Integer)
dict.Add("0", 0)
dict.Add("1", 0)
dict.Add("2", 0)
dict.Add("3", 0)
dict.Add("4", 0)
dict.Add("5", 0)
dict.Add("6", 0)
dict.Add("7", 0)
dict.Add("8", 0)
dict.Add("9", 0)
' Assuming you ask user to type into text box txtSubmittedNumber
' Parse your numbers and collect counts
For Each c as Char in txtSubmittedNumber.Text.ToCharArray()
Dim key as String = c.ToString()
dict(key) = dict(key) + 1
Next
' Assuming you fill results into listbox lstNumbers, just add your strings to display
For each kvp as KeyValuePair(of String, Integer) in dict
lstNumbers.Items.Add(kvp.Key & "=" & kvp.Value.ToString())
Next
This is program for beginners. There is Linq of course but it is not going to be as clear what is going on because it substitutes loops, group by, etc.

Number of occurrences in a string

I'm a total noob as far as visual basic goes.
In class I need to do the following: "Write a program that requests a sentence from the user and then records the number of times each letter of the alphabet occurs."
How would I go about counting the number of occurrences in the string?
Loop the chars and add to the list
Dim s As String = "tafata"
Dim count As New Dictionary(Of Char, Integer)()
For i As Integer = 0 To s.Length - 1
count(s(i)) = (If(count.ContainsKey(s(i)), count(s(i)) + 1, 1))
Next
Havent worked with linq that mutch, but i think you can try
Dim s As String = "tafata"
Dim t = From c In s _
Group c By c Into Group _
Select Group
As Dave said, the easiest solution would be to have an array of length 26 (for English), and loop through each character in the string, incrementing the correct array element. You can use the ASCII value of each character to identify which letter it is, then translate the ASCII number of the letter into the corresponding index number:
'Dimension array to 26 elements
Dim LetterCount(0 to 25) As Long
'Temporary index number
Dim tmpIdx As Long
'Temporary character
Dim tmpChar as String
'String to check
Dim checkStr As String
checkStr = "How many of each letter is in me?"
'Change all letters to lower case (since the upper case
'of each letter has a different ASCII value than its
'lower case)
checkStr = LCase(checkStr)
'Loop through each character
For n = 1 to Len(checkStr)
'Get current character
tmpChar = Mid(checkStr, n, 1)
'Is the character a letter?
If (Asc(tmpChar) >= Asc("a")) And (Asc(tmpChar) <= Asc("z")) Then
'Calcoolate index number from letter's ASCII number
tmpIdx = Asc(tmpChar) - Asc("a")
'Increase letter's count
LetterCount(tmpIdx) = LetterCount(tmpIdx) + 1
End If
Next n
'Now print results
For n = 0 to 25
Print Chr(Asc("a") + n) & " - " & CStr(LetterCount(n))
Next n
The quick and dirty way:
Public Function CountInStr(ByVal value As String, ByVal find As String, Optional compare As VbCompareMethod = VbCompareMethod.vbBinaryCompare) As Long
CountInStr = (LenB(value) - LenB(Replace(value, find, vbNullString, 1&, -1&, compare))) \ LenB(find)
End Function
I would count and remove every instance of the first character, and repeat until there are no characters left. Then display the count for each character detected. Much better than looping through once for every possible character, unless you know the possible range of characters is smaller than the length of the sentence.
Imports System.Linq
Dim CharCounts = From c In "The quick brown fox jumped over the lazy dog." _
Group c By c Into Count() _
Select c, Count
from itertools import groupby
sentence = raw_input("Your sentence:")
for char,group in groupby(sorted(sentence.lower())):
print(char+": "+`len(list(group))`)

Resources