PHPOffice/PHPPresentation (PowerPoint) - how to prevent paragraph text from wrapping to a new line when in a table cell? Is there a dedicated method? - cell

Inside a table cell I have a text - a number in fact but with space thousands separators like:
123 456 789
This data is dynamic and the value can vary a lot. I need a method to prevent this number from wrapping to a new line inside cell like:
123 456
789
I need to achieve something like when using the CSS property 'white-space: nowrap'.
Here is my code:
$oShape = $currentSlide->createTableShape(3); // 3 columns
$oShape->setWidth(180);
//...
foreach ($seriesData as $data) {
$oRow = $oShape->createRow();
//...
$oCell = $oRow->nextCell();
// $oCell->setWidth(70); // I don't want to define fixed width here
$oCell->createTextRun($data['string'])->getFont()->setBold(true)->setSize(8);
$oCell->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT)->setMarginLeft(1)->setMarginTop(0)->setMarginRight(2)->setMarginBottom(0);
// ... etc. the rest of the cells that I don't have a problem with
The issue is that the paragraph inside this cell often wraps to a new line.
Is there a dedicated method or property for no wrap in such case?

Related

Skip translating words with %% and [] in Google Sheets

I am using GoogleTranslate() with Sheets to translate some contents into different languages. In those contents, we have multiple hooks [ ] and % % in one string that do not need to translate. Example :
[name] [surname] looked at your profile %number% !
I do not need to translate hooks like [username] and %number%.
I'm looking for :
[name] [surname] a regardé ton profil %number% ! (in french for example)
A solution is already provided here for one character using REGEXREPLACE and REGEXEXTRACT. But I need either symbol [xxx] and %xxx% in one formula. Thank you.
Alternatively, instead of using the GOOGLETRANSLATE with multiple nested functions, you can try creating a bound script on your spreadsheet file & then copy/paste the simple custom script below that contains translate() function for a more simplified use of function on your sheet:
CUSTOM SCRIPT
function translate(range) {
var container = [];
//KEEP ALL %***% and [***] INTO A CONTAINER
var regex = /(\[.*?])|(\%.*?%)/gm,
stringTest = range,
matched;
while(matched = regex.exec(stringTest)){
container.push(matched[0]);
}
//TRANSLATE TEXT TO FRENCH FROM ENGLISH W/O %***% and [***]
var replacedData = stringTest.replace(regex,'#');
var toTranslate = LanguageApp.translate(replacedData, 'en', 'fr');
var res = "";
//REARRANGE THE TRANSLATED TEXT WITH %***% and [***] FROM CONTAINER
for(x=0;x<toTranslate.split("#").length;x++){
res = res + toTranslate.split("#")[x]+" "+container[x];
}
//RETURN FINAL TRANSLATED TEXT WITH UNMODIFIED %***% and [***]
return res.trim().replace("undefined","");
}
SAMPLE RESULT
After saving the script, just simply put =translate(A1) (e.g. the text you want to translate is on cell A1) on a sheet cell and the script will skip any multiple words inside [***] & %***%, then it will only translate the rest of the text to french.
Try this:
=arrayformula(if(A1<>"",join("",if(isnumber(flatten(split(GOOGLETRANSLATE(join(" ",iferror(regexreplace(to_text(flatten(split(A1," "))),"(\[.*\])|(\%.*\%)","["&row(A$1:A)&"]"),)),"en","fr"),"[]"))),vlookup(flatten(split(GOOGLETRANSLATE(join(" ",iferror(regexreplace(to_text(flatten(split(A1," "))),"(\[.*\])|(\%.*\%)","["&row(A$1:A)&"]"),)),"en","fr"),"[]")),{sequence(len(regexreplace(A1,"[^\ ]",))+1,1),flatten(split(A1," "))},2,false),flatten(split(GOOGLETRANSLATE(join(" ",iferror(regexreplace(to_text(flatten(split(A1," "))),"(\[.*\])|(\%.*\%)","["&row(A$1:A)&"]"),)),"en","fr"),"[]")))),))
GOOGLETRANSLATE does not work with ARRAYFORMULA, but you can drag down this formula from cell B1 if you want to apply it to multiple rows in column A.
Individual steps taken:
Split text by space character, then flatten into one column.
Cell D1: =flatten(split(A1," "))
Replace [***] and %***% with [row#].
Cell E1: =arrayformula(iferror(regexreplace(to_text(flatten(split(A1," "))),"(\[.*\])|(\%.*\%)","["&row(A$1:A)&"]"),))
Join the rows into one cell.
Cell F1: =join(" ",E:E)
Apply Google Translate.
Cell G1: =GOOGLETRANSLATE(F1,"en","fr")
Split by [].
Cell H1: =flatten(split(G1,"[]"))
Where rows contain numbers, lookup item 1) above.
Cell I1: =arrayformula(if(isnumber(H1:H),vlookup(H1:H,{row(A$1:A),D:D},2,false),H1:H))
Join the rows into one cell.
Cell J1: =join(" ",I:I)

Google Sheets: How can I extract partial text from a string based on a column of different options?

Goal: I have a bunch of keywords I'd like to categorise automatically based on topic parameters I set. Categories that match must be in the same column so the keyword data can be filtered.
e.g. If I have "Puppies" as a first topic, it shouldn't appear as a secondary or third topic otherwise the data cannot be filtered as needed.
Example Data: https://docs.google.com/spreadsheets/d/1TWYepApOtWDlwoTP8zkaflD7AoxD_LZ4PxssSpFlrWQ/edit?usp=sharing
Video: https://drive.google.com/file/d/11T5hhyestKRY4GpuwC7RF6tx-xQudNok/view?usp=sharing
Parameters Tab: I will add words in columns D-F that change based on the keyword data set and there will often be hundreds, if not thousands, of options for larger data sets.
Categories Tab: I'd like to have a formula or script that goes down the columns D-F in Parameters and fills in a corresponding value (in Categories! columns D-F respectively) based on partial match with column B or C (makes no difference to me if there's a delimiter like a space or not. Final data sheet should only have one of these columns though).
Things I've Tried:
I've tried a bunch of things. Nested IF formula with regexmatch works but seems clunky.
e.g. this formula in Categories! column D
=IF(REGEXMATCH($B2,LOWER(Parameters!$D$3)),Parameters!$D$3,IF(REGEXMATCH($B2,LOWER(Parameters!$D$4)),Parameters!$D$4,""))
I nested more statements changing out to the next cell in Parameters!D column (as in , manually adding $D$5, $D$6 etc) but this seems inefficient for a list thousands of words long. e.g. third topic will get very long once all dog breed types are added.
Any tips?
Functionality I haven't worked out:
if a string in Categories B or C contains more than one topic in the parameters I set out, is there a way I can have the first 2 to show instead of just the first one?
e.g. Cell A14 in Categories, how can I get a formula/automation to add both "Akita" & "German Shepherd" into the third topic? Concatenation with a CHAR(10) to add to new line is ideal format here. There will be other keywords that won't have both in there in which case these values will just show up individually.
Since this data set has a bunch of mixed breeds and all breeds are added as a third topic, it would be great to differentiate interest in mixes vs pure breeds without confusion.
Any ideas will be greatly appreciated! Also, I'm open to variations in layout and functionality of the spreadsheet in case you have a more creative solution. I just care about efficiently automating a tedious task!!
Try using custom function:
To create custom function:
1.Create or open a spreadsheet in Google Sheets.
2.Select the menu item Tools > Script editor.
3.Delete any code in the script editor and copy and paste the code below into the script editor.
4.At the top, click Save save.
To use custom function:
1.Click the cell where you want to use the function.
2.Type an equals sign (=) followed by the function name and any input value — for example, =DOUBLE(A1) — and press Enter.
3.The cell will momentarily display Loading..., then return the result.
Code:
function matchTopic(p, str) {
var params = p.flat(); //Convert 2d array into 1d
var buildRegex = params.map(i => '(' + i + ')').join('|'); //convert array into series of capturing groups. Example (Dog)|(Puppies)
var regex = new RegExp(buildRegex,"gi");
var results = str.match(regex);
if(results){
// The for loops below will convert the first character of each word to Uppercase
for(var i = 0 ; i < results.length ; i++){
var words = results[i].split(" ");
for (let j = 0; j < words.length; j++) {
words[j] = words[j][0].toUpperCase() + words[j].substr(1);
}
results[i] = words.join(" ");
}
return results.join(","); //return with comma separator
}else{
return ""; //return blank if result is null
}
}
Example Usage:
Parameters:
First Topic:
Second Topic:
Third Topic:
Reference:
Custom Functions
I've added a new sheet ("Erik Help") with separate formulas (highlighted in green currently) for each of your keyword columns. They are each essentially the same except for specific column references, so I'll include only the "First Topic" formula here:
=ArrayFormula({"First Topic";IF(A2:A="",,IFERROR(REGEXEXTRACT(LOWER(B2:B&C2:C),JOIN("|",LOWER(FILTER(Parameters!D3:D,Parameters!D3:D<>""))))) & IFERROR(CHAR(10)&REGEXEXTRACT(REGEXREPLACE(LOWER(B2:B&C2:C),IFERROR(REGEXEXTRACT(LOWER(B2:B&C2:C),JOIN("|",LOWER(FILTER(Parameters!D3:D,Parameters!D3:D<>""))))),""),JOIN("|",LOWER(FILTER(Parameters!D3:D,Parameters!D3:D<>""))))))})
This formula first creates the header (which can be changed within the formula itself as you like).
The opening IF condition leaves any row in the results column blank if the corresponding cell in Column A of that row is also blank.
JOIN is used to form a concatenated string of all keywords separated by the pipe symbol, which REGEXEXTRACT interprets as OR.
IFERROR(REGEXEXTRACT(LOWER(B2:B&C2:C),JOIN("|",LOWER(FILTER(Parameters!D3:D,Parameters!D3:D<>""))))) will attempt to extract any of the keywords from each concatenated string in Columns B and C. If none is found, IFERROR will return null.
Then a second-round attempt is made:
& IFERROR(CHAR(10)&REGEXEXTRACT(REGEXREPLACE(LOWER(B2:B&C2:C),IFERROR(REGEXEXTRACT(LOWER(B2:B&C2:C),JOIN("|",LOWER(FILTER(Parameters!D3:D,Parameters!D3:D<>""))))),""),JOIN("|",LOWER(FILTER(Parameters!D3:D,Parameters!D3:D<>"")))))
Only this time, REGEXREPLACE is used to replace the results of the first round with null, thus eliminating them from being found in round two. This will cause any second listing from the JOIN clause to be found, if one exists. Otherwise, IFERROR again returns null for round two.
CHAR(10) is the new-line character.
I've written each of the three formulas to return up to two results for each keyword column. If that is not your intention for "First Topic" and "Second Topic" (i.e., if you only wanted a maximum of one result for each of those columns), just select and delete the entire round-two portion of the formula shown above from the formula in each of those columns.

Bulk find-and-replace regexs in Google Sheets

Is there a function, script, or add-on that can apply a large series of regex replacements to a range of data in Google Sheets? I have one sheet with a list of addresses and another with several dozen pairs of regular expressions in two columns (e.g. "St.$" and "Street"), and I want to replace all instances of the first column of phrases in the address list with the corresponding phrase in the other.
This question was initially closed as being answered by this, but even after some significant tweaking to fit my situation, I can only get that formula to replace one phrase per address, and any other matching phrases will be replaced by the first word (so "1234 N. Main St." becomes "1234 North Main North" instead of "1234 North Main Street"). Is there a method that specifically doesn't do that?
Assuming all your data is in a single column, here's a script (much cleaner and more extensible than the formula approach):
Note: this is not an in-place replacement.
function processColumn(column)
{
// Add more as needed:
// [Regex, Replacement]
let replaceTable =
[
[/\bN\./g, 'North'],
[/\bS\./g, 'South'],
[/\bSt\./g, 'Street']
];
// A column is an array of rows
// A row is an array of values.
return column.map(row =>
// This is an optimization to skip over blank values
row[0]
? replaceTable.reduce(
// Replace one value at a time, in order
(curString, tableEntry) => curString.replace(tableEntry[0], tableEntry[1]),
row[0]
)
: ''
);
}
Usage Example:
All your data is in A:A, like so:
A
123 N. Main St.
124 N. Main St.
19 S. Main St.
Then in column B:
=processColumn(A:A)
This will place all the processed values in column B:
B
123 North Main Street
124 North Main Street
19 South Main Street
Possibly this:
values = sheet.getDataRange().getDisplayValues()
values = values.map(outer => outer.map(inner => inner
.replaceAll(/\bN\./g, 'North')
.replaceAll(/\bS\./g, 'South')
.replaceAll(/\bSt\./g, 'Street')
)
);
Change this values = sheet.getDataRange().getDisplayValues() to what ever you need

Removing a row containing a specific text in Google Sheets

I have a data set of around 3000 columns, but some of the columns have several cells that contain cells "na". These rows have no importance since they don't have data that I will need, is there a command in google sheets that can either highlight the entire row that contains that text or delete the entire row containing that text?
Any help would be appreciated.
https://docs.google.com/spreadsheets/d/1u8OUfQOzgAulf1a8bzQ8SB5sb5Uvb1I4amF5sdGEBlc/edit?usp=sharing
My document ^.
you can use this formula to color all na rows:
=ARRAYFORMULA(REGEXMATCH(TRANSPOSE(QUERY(TRANSPOSE($A1:$Z),,999^99)), " na "))
This answer based on what I understand, sorry if I'm wrong. You can use conditional formatting to highlight all NA text
This is what rules I used
Here are another answers that may help you
Delete a row in Google Spreadsheets if value of cell in said row is 0 or blank
Google Sheets: delete rows containing specified data
Deleting Cells in Google Sheets without removing a whole row
Sorry for bad English.
I'm not sure if my understing is well but see below what you can do.
This is a google script function which color the whole column where "na" is in
function myFunction() {
//get the spreadsheet where the function is running
var ss = SpreadsheetApp.getActive()
//Replace "the name of your sheet" by your sheet name" be careful its case sensitive.
var sheet = ss.getSheetByName("The name of your sheet")
//Get all your data as an array (If your sheet has no header, change 2 by 1 and (sheet.getLastRow()-1) by sheet.getLastRow())
var values = sheet.getRange(2,1,(sheet.getLastRow()-1), sheet.getLastColumn()).getValues();
//For each column
for (var i = 0; i< sheet.getLastColumn(); i++){
//using function map is helping to select one column by one column
var mapValues = values.map(function(r){return r[i]});
//Searching your keyword in the column, in your case it's "na"
var position = mapValues.indexOf("Put the string that you are looking for, in your case 'na'");
//if at least there is one "na" inside the column
if( position >-1){
//then this color have to get red color as a background
var wholeColumn = sheet.getRange(2,(i+1),(sheet.getLastRow()-1));
wholeColumn.setBackground("red");
}
}
}``
Let me know if it works

Search for an item in a text file using UIMA Ruta

I have been trying to search for an item which is there in a text file.
The text file is like
Eg: `
>HEADING
00345
XYZ
MethodName : fdsafk
Date: 23-4-2012
More text and some part containing instances of XYZ`
So I did a dictionary search for XYZ initially and found the positions, but I want only the 1st XYZ and not the rest. There is a property of XYZ that , it will always be between the 5 digit code and the text MethondName .
I am unable to do that.
WORDLIST ZipList = 'Zipcode.txt';
DECLARE Zip;
Document
Document{-> MARKFAST(Zip, ZipList)};
DECLARE Method;
"MethodName" -> Method;
WORDLIST typelist = 'typelist.txt';
DECLARE type;
Document{-> MARKFAST(type, typelist)};
Also how do we use REGEX in UIMA RUTA?
There are many ways to specify this. Here are some examples (not tested):
// just remove the other annotations (assuming type is the one you want)
type{-> UNMARK(type)} ANY{-STARTSWITH(Method)};
// only keep the first one: remove any annotation if there is one somewhere in front of it
// you can also specify this with POSISTION or CURRENTCOUNT, but both are slow
type # #type{-> UNMARK(type)}
// just create a new annotation in between
NUM{REGEXP(".....")} #{-> type} #Method;
There are two options to use regex in UIMA Ruta:
(find) simple regex rules like "[A-Za-z]+" -> Type;
(matches) REGEXP conditions for validating the match of a rule element like
ANY{REGEXP("[A-Za-z]+")-> Type};
Let me know if something is not clear. I will extend the description then.
DISCLAIMER: I am a developer of UIMA Ruta