Remove Leading Zero(s) For Each Section Separated by '.' Except When '.0.' - leading-zero

In TSQL I need to create a script to remove all leading zero's between '.', starting with the first 0 in the string EXCEPT when there is a '.0.' anywhere in the middle of the task number. What I have so far does fine when the task number does not have EX: 111.0.123.234, but I cannot seem to figure out the combination of SUBSTRING/CHARINDEX/PATINDEX, etc. to remove all leading zeros except when the zero is the only number between '.' See attached screenshot and script/partial results as an example.
Here is my script:
SELECT TASKPRODUCTID, (CASE WHEN TASKPRODUCTID NOT LIKE '%.0.%' THEN
REPLACE(LTRIM(REPLACE(TASKPRODUCTID,'0','')),' ','0') ELSE
SUBSTRING(TASKPRODUCTID, PATINDEX('%[^0 ]%', TASKPRODUCTID + ' '), LEN(TASKPRODUCTID))
END) AS NewTaskProductID
FROM TASK
Here is a partial resultset:
TASKPRODUCTID NewTaskProductID
003.007.002.001 3.7.2.1
003.007.002.003 3.7.2.3
004.003.003.008.0.2017275.132925 4.003.003.008.0.2017275.132925
004.005.001.003 4.5.1.3
004.005.004.004.0.2017275.135139 4.005.004.004.0.2017275.135139
004.005.007.005.0.2017275.140304 4.005.007.005.0.2017275.140304
002.001.002 2.1.2
002.004 2.4
016.010 16.1
Screenshot Example of leading zero in highlighted rows still have leading zeros in next decimal section(s)
Thank you!!

You could try using the STUFF() to get the .0. in the else case scenario
declare #s AS varchar(100) = '0010.0.005.006025'
print stuff(REPLACE(LTRIM(REPLACE(#s,'0','0')),'0','*'),
patindex('%.*.%',REPLACE(LTRIM(REPLACE(#s,'0','0')),'0','*')), 3,'.-.')
OUTPUT
**1*.-.**5.**6*25
Now treat this as first scenario ; only difference is that we have got '*' instead of '0'

Related

Remove all whitespace from string AX 2012

PurchPackingSlipJournalCreate class -> initHeader method have a line;
vendPackingSlipJour.PackingSlipId = purchParmTable.Num;
but i want when i copy and paste ' FDG 2020 ' (all blanks are tab character) in Num area and click okey, write this value as 'FDG2020' in the PackagingSlipId field of the vendPackingSlipJour table.
I tried -> vendPackingSlipJour.PackingSlipId = strRem(purchParmTable.Num, " ");
but doesn't work for tab character.
How can i remove all whitespace characters from string?
Version 1
Try the strAlpha() function.
From the documentation:
Copies only the alphanumeric characters from a string.
Version 2
Because version 1 also deletes allowed hyphens (-), you could use strKeep().
From the documentation:
Builds a string by using only the characters from the first input string that the second input string specifies should be kept.
This will require you to specify all desired characters, a rather long list...
Version 3
Use regular expressions to replace any unwanted characters (defined as "not a wanted character"). This is similar to version 2, but the list of allowed characters can be expressed a lot shorter.
The example below allows alphanumeric characters(a-z,A-Z,0-9), underscores (_) and hyphens (-). The final value for newText is ABC-12_3.
str badCharacters = #"[^a-zA-Z0-9_-]"; // so NOT an allowed character
str newText = System.Text.RegularExpressions.Regex::Replace(' ABC-12_3 ', badCharacters, '');
Version 4
If you know the only unwanted characters are tabs ('\t'), then you can go hunting for those specifically as well.
vendPackingSlipJour.PackingSlipId = strRem(purchParmTable.Num, '\t');

SQLite SUM Problem, it does not sum correctly?

Hello there and good morning!
I have a litte problem with the Database of the Time Tracking Software of our company.
The first problem: the time is in a dumb format. If someone works 7h 30m, the database writes 7,30 as value. So far so good. So I have to split the decimals, convert it to industrial time, and put it back together. So far so good. It works, if the value is under 10. Above 10, the value converts itself into INT. But that case should be intercepted by my code.
Here's the code:
SELECT PersNr, Name, CASE WHEN substr(IstStd,3,1) LIKE ',' OR '.' THEN (SUM(CASE WHEN (substr(IstStd,4,2)/60 NOT LIKE 0) THEN ROUND((substr(IstStd,4,2))/60 + (substr(IstStd,1,2)),2) ELSE (IstStd) END)) ELSE (SUM(CASE WHEN (substr(IstStd,3,2)/60 NOT LIKE 0) THEN ROUND((substr(IstStd,3,2))/60 + (substr(IstStd,1,1)),2) ELSE (IstStd) END)) END AS IstStd
FROM ARCHIV_JOURNAL WHERE PersNr ='3041' AND Datum BETWEEN '2019-10-01' AND '2019-10-31'
As you can see in the first CASE, I check if the third character is , or . . The Code works fine, just not for 10h+.
Did I miss something? I'd appreciate any help with that.
If you need more information, just hit me back.
Thank you in advance and have a nice day!
The condition:
WHEN substr(IstStd,3,1) LIKE ',' OR '.'
is not correct.
It is interpreted as:
WHEN (substr(IstStd,3,1) LIKE ',') OR ('.')
If you want to check if the 3d char is ',' or '.' you must do:
WHEN substr(IstStd,3,1) IN (',', '.')
Also in other parts of your code you use the operator LIKE when you should use = or <>.
Change to this:
SELECT PersNr, Name,
CASE
WHEN substr(IstStd,3,1) IN (',', '.')
THEN SUM(
CASE
WHEN (substr(IstStd,4,2)/60 <> 0) THEN ROUND((substr(IstStd,4,2))/60 + (substr(IstStd,1,2)),2)
ELSE (IstStd)
END
)
ELSE SUM(
CASE
WHEN (substr(IstStd,3,2)/60 <> 0) THEN ROUND((substr(IstStd,3,2))/60 + (substr(IstStd,1,1)),2)
ELSE (IstStd)
END
)
END AS IstStd
FROM ARCHIV_JOURNAL
WHERE PersNr ='3041' AND Datum BETWEEN '2019-10-01' AND '2019-10-31'
Also when you divide integers the result is also an integer.
If you want the result of the division:
substr(IstStd,3,2))/60
to be a decimal number, then change it to:
substr(IstStd,3,2))/60.0

Format zero currency value with {0:C} in VB.Net

I am trying to format a zero currency value as an empty string, so that when the currency value is 0.00 then an empty string gets displayed rather than $0.00.
This code is part of an ASP.Net app that will display currency value to end user.
I have used following code to achieve this goal.
Question : Is it possible to achieve this by just using {0:C} format string or another version of this format string instead of using if then else coding for this? If I use ###,###,###.## as the data format string then an empty string shows for zero currency value and also I get rid of the if then else coding but for non-zero values no currency symbol shows.
If Double.Parse(Decimal.Parse(CDec(currencyValue))) = 0 Then
charValue = Nothing
Else
charValue = String.Format("{0:C}", CDec(currencyValue))
End If
UPDATE
I ended up using the following code, which is working fine. If is better than IIf because it does short-circuiting, which means that IIf will evaluate all expressions whether the condition is true or false but If will evaluate the first expression only if condition is true and evaluate the second expression only if condition is false.
Dim d As Decimal
Decimal.TryParse(currencyValue, d)
charValue = If(d = 0D, Nothing, String.Format("{0:C}", d))
I don't think there is a way using formatting to display an empty string.
But you can write it like:
charValue = If( currencyValue = 0D, "", currencyValue.ToString("C") )
using the If Operator (Visual Basic).
Also this is something I would not do:
If Double.Parse(Decimal.Parse(CDec(currencyValue))) = 0 Then
If currencyValue is Decimal:
If (currencyValue = 0D) Then
If currencyValue is Double:
If (currencyValue = 0R) Then
Also, if you are using a database and this is a Sql Server mind SQL Server Data Type Mappings
I don't think you can when using C or the other similar standard formats, since they are already defining a culture-specific format that will include a format for zero.
But if you specify your own custom format, you can specify three different formats separated by ;s, one each for positive numbers, negative numbers, and zero, respectively.
For example (giving an empty string for the zero format, resulting in blank zeroes):
charValue = String.Format("{0:#,##0.00;-#,##0.00;""""}", CDec(currencyValue))
And from what I can see, omitting the format for negative gives a default that matches the positive, whereas omitting the format for zero gives blank, which is what you're looking for, so this should be sufficient as well:
charValue = String.Format("{0:#,##0.00;;}", CDec(currencyValue))
(Using whichever custom format you wish.)
UPDATE: You can get the current currency symbol and manually put it into your custom format. IE:
Dim symbol = CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol
charValue = String.Format("{0}{1:#,##0.00;;}", symbol, CDec(currencyValue))
From the sound of it, though, I think I would actually recommend doing basically what you started with, maybe with an extension method.
<Extension>
Public Function ToCurrencyString(pValue As Decimal) As String
Return IIf(pValue = 0, "", pValue.ToString("C"))
End Function
Dim someValue As Decimal = 1.23
Console.WriteLine(someValue.ToCurrencyString())
This gives you exactly what you're looking for. The exact same format as C gives, but with blank zeroes.

Substring with Multiple Arguments

I have a dropdownlist that has the value of two columns in it... One column is a number ranging from 5 characters long to 8 characters long then a space then the '|' character and another space, followed by a Description for the set of numbers.
An example:
12345678 | Description of Product
In order to pull the items for the dropdownlist into my database I need a to utilize a substring to pull the sequence of numbers out only.
Is it possible to write a substring to pull multiple character lengths? (Sometimes it may be 6 numbers, sometimes 5 numbers, sometimes 8, it would depend on what the user selected from the dropdownlist.)
Use a regular expression for this.
Assuming the number is at the start of the string, you can use the following:
^[0-9]+
Usage:
var theNumbers = RegEx.Match(myDropdownValue, "^[0-9]+").Value;
You could also use string.Split to get the parts separated by | if you know the first part is what you need and will always be numeric:
var theNumbers = myDropdownValue.Split("| ".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries)[0];
Either of these approaches will result in a string. You can use int.Parse on the result in order to get an integer from it.
This is how I would do it
string str = "12345678 | Description of Product";
int delimiter;
delimiter = str.IndexOf("|") - 1;
string ID =str.substring(0, delimiter);
string desc = str.substring(delimiter + 1, str.length - 1);
Try using a regex to pull out the first match of a sequence of numbers of any length. The regex will look something like "^\d+" - starts with any number of decimal digits.
Instead of using substring, you should use Split function.
var words = phrase.Split(new string[] {" | "},
StringSplitOptions.RemoveEmptyEntries);
var number = word[0];

xQuery substring problem

I now have a full path for a file as a string like:
"/db/Liebherr/Content_Repository/Techpubs/Topics/HyraulicPowerDistribution/Released/TRN_282C_HYD_MOD_1_Drive_Shaft_Rev000.xml"
However, now I need to take out only the folder path, so it will be the above string without the last back slash content like:
"/db/Liebherr/Content_Repository/Techpubs/Topics/HyraulicPowerDistribution/Released/"
But it seems that the substring() function in xQuery only has substring(string,start,len) or substring(string,start), I am trying to figure out a way to specify the last occurence of the backslash, but no luck.
Could experts help? Thanks!
Try out the tokenize() function (for splitting a string into its component parts) and then re-assembling it, using everything but the last part.
let $full-path := "/db/Liebherr/Content_Repository/Techpubs/Topics/HyraulicPowerDistribution/Released/TRN_282C_HYD_MOD_1_Drive_Shaft_Rev000.xml",
$segments := tokenize($full-path,"/")[position() ne last()]
return
concat(string-join($segments,'/'),'/')
For more details on these functions, check out their reference pages:
fn:tokenize()
fn:string-join()
fn:replace can do the job with a regular expression:
replace("/db/Liebherr/Content_Repository/Techpubs/Topics/HyraulicPowerDistribution/Released/TRN_282C_HYD_MOD_1_Drive_Shaft_Rev000.xml",
"[^/]+$",
"")
This can be done even with a single XPath 2.0 (subset of XQuery) expression:
substring($fullPath,
1,
string-length($fullPath) - string-length(tokenize($fullPath, '/')[last()])
)
where $fullPath should be substituted with the actual string, such as:
"/db/Liebherr/Content_Repository/Techpubs/Topics/HyraulicPowerDistribution/Released/TRN_282C_HYD_MOD_1_Drive_Shaft_Rev000.xml"
The following code tokenizes, removes the last token, replaces it with an empty string, and joins back.
string-join(
(
tokenize(
"/db/Liebherr/Content_Repository/Techpubs/Topics/HyraulicPowerDistribution/Released/TRN_282C_HYD_MOD_1_Drive_Shaft_Rev000.xml",
"/"
)[position() ne last()],
""
),
"/"
)
It seems to return the desired result on try.zorba-xquery.com. Does this help?

Resources