I have a two column table: TYPE and VALUE, with both columns' values being of the type INT.
I must format Value.value in an SSRS paginated report using "+" and "-" to denote the value's sign, and with parenthesis, i.e. "(value)" or without parenthesis as determined by the column TYPE. If the value of TYPE is > x, then parentheses; else, no parentheses.
I commonly see negative values formatted with parenthesis, i.e. (1,000), but in this case I can't use that standard.
Here's an example of the four solutions I seek, exemplified by the values -1,000 or 1,000, having TYPE > or < x, respectively:
(-1,000)
-1,000
(+1,000)
+1,000
SSRS reports' user interface seems to allow custom expressions for both VALUE and FORMAT. In this instance, I'm creating a custom VALUE expression but not a custom expression for FORMAT (it's possible a solution might combine custom expressions using both).
Here's my attempt, which isn't working (object error).
=iif(TYPE.value > x AND VALUE.value > 0, "(+"&VALUE.value&")"),
iif(TYPE.value > x AND VALUE.value < 0, "(-"&*VALUE.value&")"),
iif(TYPE.value < x AND VALUE.value < 0, "-"&VALUE.value,
"+"&VALUE.value)
Welcome any guidance. Tks!
There are a few typo's in your expression, for example you need to reference the Fields collection ( Fields!Value.Value etc. ) and you have an * in there for some reason.
Anyway, there is simpler way to do this.
Don't change the value expression, just change the format expression of the text box.
In the number format string you can specify how positive and negative numbers are displayed so all you really need to determine is if Value > X
I created some sample data with the following dataset query
DECLARE #t TABLE (X int, Value int)
INSERT INTO #t VALUES
(1,2),
(3,2),
(-10, -11),
(-2234, -1234)
SELECT * FROM #t
I then added a table. The first two columns show the actual numbers with NO formatting.
The third column shows the formatted output.
The report design looked like this (note that the 3rd column shows [Value] as I have not made any changes to the value expression
In the Format property of the 3rd cell I used the following expression
=IIF(
Fields!Value.Value > Fields!X.Value,
"(+#,0);-#,0",
"+#,0;(-#,0)"
)
This simply reads
"If Value > X then format +ve numbers in parentheses with a + sign,
and -ve numbers with no parentheses and a minus sign, ELSE, format +ve
numbers with a plus sign and -ve numbers in parentheses with a -sign"
Which gives the following output.
Related
So in my PostgreSQL 10 I have a column of type integer. This column represents a code of products and it should be searched against another code or part of the code. The values of the column are made of three parts, a five-digit part and two two-digit parts. Users can search for only the first part, the first-second or first-second-third.
So, in my column I have , say 123451233 the user searches for 12345 (the first part). I want to be able to return the 123451233. Same goes if the users also searches for 1234512 or 123451233.
Unfortunately I cannot change the type of column or break the one column into three (one for every part). How can I do this? I cannot use LIKE. Maybe something like a regex for integers?
Thanks
Consider to use simple arithmetic.
log(value)::int + 1 returns the number of digits in integer part of the value and using this:
value/(10^(log(value)::int-log(search_input)::int))::int
returns value truncated to the same digits number as search_input so, finally
search_input = value/(10^(log(value)::int-log(search_input)::int))::int
will make the trick.
It is more complex literally but also could be more efficient then strings manipulations.
PS: But having index like create index idx on your_table(cast(your_column as text)); search like
select * from your_table
where cast(your_column as text) like search_input || '%';
is the best case IMO.
You do not need regex functions. Cast the integer to text and use the function left(), example:
create table my_table(code int); -- or bigint
insert into my_table values (123451233);
with input_data(input_code) as (
values('1234512')
)
select t.*
from my_table t
cross join input_data
where left(code::text, length(input_code)) = input_code;
code
-----------
123451233
(1 row)
I'm trying to write a formula for Google Sheets which will convert Unicode characters with diacritics to their plain ASCII equivalents.
I see that Google uses RE2 in its "REGEXREPLACE" function. And I see that RE2 offers Unicode character classes.
I tried to write a formula (similar to this one):
REGEXREPLACE("público","(\pL)\pM*","$1")
But Sheets produces the following error:
Function REGEXREPLACE parameter 2 value "\pL" is not a valid regular expression.
I suppose I could write a formula consisting of a long set of nested SUBSTITUTE functions (Like this one), but that seems pretty awful.
Can any offer a suggestion for a better way to normalize Unicode letters with diacritical/accent marks in a Google Sheets formula?
[[:^alpha:]] (negated ASCII character class) works fine for REGEXEXTRACT formula.
But =REGEXREPLACE("público","([[:alpha:]])[[:^alpha:]]","$1") gives "pblic" as a result. So, I guess, formula doesn't know what exact ASCII character must replace "ú".
Workaround
Let's take the word públicē; we need to replace two symbols in it. Put this word in cell A1, and this formula in cell B1:
=JOIN("",ArrayFormula(IFERROR(VLOOKUP(SPLIT(REGEXREPLACE(A1,"(.)","$1-"),"-"),D:E,2,0),SPLIT(REGEXREPLACE(A1,"(.)","$1-"),"-"))))
And then make directory of replacements in range D:E:
D E
1 ú u
2 ē e
3 ... ...
This formula is still ugly, but more useful because you can control your directory by adding more characters to the table.
Or use Java Script
Also found a good solution, which works in google sheets.
This did it for me in Google Sheets, Google Apps Scripts, GAS
function normalizetext(text) {
var weird = 'öüóőúéáàűíÖÜÓŐÚÉÁÀŰÍçÇ!#£$%^&*()_+?/*."';
var normalized = 'ouooueaauiOUOOUEAAUIcC ';
var idoff = -1,new_text = '';
var lentext = text.toString().length -1
for (i = 0; i <= lentext; i++) {
idoff = weird.search(text.charAt(i));
if (idoff == -1) {
new_text = new_text + text.charAt(i);
} else {
new_text = new_text + normalized.charAt(idoff);
}
}
return new_text;
}
This answer doesn't require a Google App Script, and it's still fast, and relatively simple. It builds on Max's answer by providing a full lookup table, and it also allows for case-sensitive transliteration (normally VLOOKUP is NOT case-sensitive).
Here is a link to the Google Spreadsheet if you want to jump right into it. If you want to use your own sheet, you'll need to copy the TRANS_TABLE sheet into your Spreadsheet.
In the code snippet below, the source cell is A2, so you'd place this formula in any column on row 2. Using REGEXREPLACE AND SPLIT, we split apart the string in A2 into an array of characters, then USING ARRAYFORMULA, we do the following to EACH character in the array: First, the character is converted to its 'decimal' CODE equivalent, then matched against a table on the TRANS_TABLE sheet by that number, then using VLOOKUP, a character X number of columns over (the index value provided) on the TRANS_TABLE sheet (in this case, the 3rd column over) is returned. When all characters in the array have been transliterated, we finally JOIN the array of characters back into a single string. I provided examples with named ranges as well.
=iferror(
join(
"",
ARRAYFORMULA(
vlookup(
code(split(REGEXREPLACE($A2,"(.)", "$1;"),";",TRUE)),
TRANS_TABLE!$A$5:$F,3
)
)
)
,)
You'll note on the TRANS_TABLE sheet I made, I created 4 different transliteration columns, which makes it easy to have a column for each of your transliteration needs. To reference the column, just use a different index number in the VLOOKUP. Each column is simply a replacement character column. In some cases, you don't want any conversion made (A -> A or 3 -> 3), so you just copy the same character from the source Glyph column. Where you DO want to convert characters, you type in whatever character you want replaced (ñ -> n etc). If you want a character removed altogether, you leave the cell blank (? -> ''). You can see examples of the transliteration output on the data sheet in which I created 4 different transliteration columns (A-D) referencing each of the Transliteration tables from the TRANS_TABLE sheet for different use case scenarios.
I hope this finally answers your question in a fashion that isn't so "ugly." Cheers.
I just cannot get this working. i want to subset all the rows containing "mail". I use this:
Email <- subset(Total_Content, source == ".*mail.*")
I have rows like this ones:
"snt152.mail.live.com",
"mailing.serviciosmovistar.com",
"blu179.mail.live.com"
But when using: "View(Email)"
I just get a data.frame empty (just see the columns). I don't need to "scape" any metacharacter, because i need the "." to mean "anycharacter" and the "*" (0 or more times), right? Thanks.
Well, no, it doesn't - it's not meant to. You're not passing it a regular expression to be evaluated against each row, you're just passing it a character string; it doesn't know that . and * are regex characters because it's not performing a regex search. It's returning all rows where source is the literal string .mail. - which in this case is 0 rows.
What you probably want to be doing (I'm assuming this is a data.frame, here) is:
Email <- Total_Content[grepl(x = Total_Content$source, pattern = ".*mail.*"),]
grepl produces a set of boolean values of whether each entry in Total_Content$source matched the pattern. Total_Content[boolean_vector,] limits to those rows of Total_Content where the equivalent boolean is TRUE.
Why not use subset with a logical regex funtion?
Email <- subset(Total_Content, grepl(".*mail.*", source) )
The subset function does create a local environment for the evaluation of expressions that are used in either the 'subset' (row targets) or the 'select' (column targets) arguments.
How can I use regular expression in excel ?
In above image I have column A and B. I have some values in column A. Here I need to move data after = in column B. For e.g. here in 1st row I have SELECT=Hello World. Here I want to remove = sign and move Hello world in column B. How can I do such thing?
Stackoverflow has many posts about adding regular expressions to Excel using VBA. For your particular example, you would need VBA to actually move a substring from one cell to another.
If you simply want to copy the substring, you can do so easily using the MID function:
=IFERROR(MID(A1,FIND("=",A1)+1,999),A1)
I used 999 to ensure that enough characters were grabbed.
IFERROR returns the cell as-is if an equals sign is not found.
To return the portion of string before the equals sign, do this:
=LEFT(A1,FIND("=",A1&"=")-1)
In this case, I appended the equals sign to A1, so FIND won't return an error if not found.
You can use the Text to Column functionality of MS-Excel giving '=' as delimiter.
Refer to this link:
Chop text in column to 60 charactersblocks
You can simply use Text to Column feature of excel for this:
Follow the below steps :
1) Select Column A.
2) Goto Data Tab in Menu Bar.
3) Click Text to Column icon.
4) Choose Delimited option and do Next and then check the Other options in delimiter and enter '=' in the entry box.
5) Just click finish.
Here are URL for Text to Column : http://www.excel-easy.com/examples/text-to-columns.html
I have a table in Oracle with a VARCHAR column called DESCRIPTION. Some of the rows contain non-printable characters such as the character with numeric value 150 (which is not in Latin-1 and is "Start of Protected Area" in Unicode).
I want to select all the rows whose DESCRIPTION columns contain a character whose numeric value is between 128 and 160. Is there a way to do this without a long list of LIKE clauses OR'ed together? I suppose it can be done with regular expressions, but I haven't found a way to do it.
I had to do something very like this recently and used some SQL like this:
with codes as (select rownum code from dual connect by level <= 160)
select distinct t.id, t.description
from mytable t, codes c
where t.description like '%' || chr(c.code) || '%'
and c.code >= 128;
Vincent's post helped me a lot with this problem! I wanted to find all rows that had any extended ASCII: 128-255, so I shortened the statement to this:
SELECT description
FROM your_table
WHERE regexp_like (description, '['||chr(128)||'-'||chr(255)||']');
Short way to grab a range.
You could use a regular expression, it may perform better than 30+ single WHERE clause but it won't be much prettier:
SELECT *
FROM your_table
WHERE regexp_like(description, '['||chr(128)||chr(129)||...||chr(160)||']')