SUBSTITUTE based on a table of replacement strings - excel

I have a list of business names and addresses in A, and shortened versions of just the business names with an added store # shown in B,
I would like to be able to paste a set of data into column D and have the file automatically find and substitute based on the info in the table, and output to column E.
The total number of potential substitutions is >200, so a nested SUBSTITUTE function would very quickly get too messy.
The sheet must handle multiples of the same entries in column D. i.e. The same business can appear multiple times in the raw data, and I want each entry to be subbed.
A4 and A5 represent the same location for my purposes, so the output needs to be the same between them.
A9 include a comma after "Sobeys", so the data formatting is not reliable enough to find the first comma and erase everything after.
This is currently being handled in Google Sheets, but if a more accessible solution exists in Excel I'd be willing to work there just for the substitutions. I've seen similar questions answered using QUERY or ARRAYFORMULA, but I'm out of my depth to try and adjust those answers to suit my needs here. Thank you!

To replace a big amount of data, try this (you have to enable the service Google Sheets API )
function replacements() {
const ar = [
{ text: "Example 1", newText: 'text1' },
{ text: "Example 2", newText: 'text2' },
{ text: "Example 3", newText: 'text3' },
];
const requests = ar.map(({ text, newText }) => ({ findReplace: { allSheets: true, find: text, replacement: newText, matchEntireCell: true, matchCase: true } }));
Sheets.Spreadsheets.batchUpdate({ requests }, SpreadsheetApp.getActive().getId());
}
You can construct the ar matrix based on your sheet in a separate spreadsheet (otherwise your table will also update). For instance
function replacements() {
var ar = []
var data = SpreadsheetApp.openById('id of the spreadsheet that contains the table').getSheets()[0].getDataRange().getValues()
data.forEach(function(r) {
var prov = {}
prov['text']=r[0]
prov['newText']=r[1]
ar.push(prov)
})
const requests = ar.map(({ text, newText }) => ({ findReplace: { allSheets: true, find: text, replacement: newText, matchEntireCell: true, matchCase: true } }));
Sheets.Spreadsheets.batchUpdate({ requests }, SpreadsheetApp.getActive().getId());
}

Related

Cypress index position to came before a specific string

I need to check a string on a Thead to come before a specific string.
User need to be before Primium like in the e.g
Here is the code I am using
it('test', () => {
cy.visit('url')
cy.wait('#geturl')
.its('response.statusCode')
.should('be.oneOf', [200, 201])
cy.url().should('include', 'url')
cy.get('h1').should('contain', 'url List')
cy.get('thead').find(`th:contains('User')`).invoke('index').as('userIndex')
cy.get('thead')
.find(`th:contains('Premium')`)
.invoke('index')
.as('premiumUndex')
cy.get('#userIndex').then((userIndex) => {
cy.get('#premiumUndex').then((premiumUndex) => {
expect(userIndex).to.be.lessThan(premiumUndex)
})
})
})
It is working, but I need to check the User column is before Premium column and after Agent column Is there a better way to do it?
Check three column headers using .slice() to get just the columns you want.
Then map elements to the text. Use .trim() if there is whitespace around it.
cy.get('thead th')
.invoke('slice', 4, 7)
.then($th => [...$th].map(th => th.innerText.trim()))
.should('deep.eq', ['Agent', 'User', 'Premium'])
The easiest way I can see is to take all the header texts as one long string and check that "AgentUserPremium" is in it.
In case there are whitespace characters like " " or "\n", add a filter to remove these.
cy.get('thead th')
.invoke('text')
.then(text => text.replace(/\s/g, ''))
.should('contain', 'AgentUserPremium')
If you are checking for headers as part of a test, the a stronger test would be to set the headers as a static variable within your test and then use .each() to check each header in the table.
const headers = [
"",
"Number",
"Code",
"Client",
"Agent",
"User",
"Premium",
"Status",
"Time",
"",
];
cy.get("th")
.should("have.length", headers.length)
.each((header, index) => {
expect(header).to.have.text(headers[index]);
});
Here is a working example based on the screenshot.

Multiple Select in Tabulator

Is it possible to have one select field depend on the previous one?
Users select one value from select_1 then accordingly the value in select_2 change. Maybe a custom formatter?
const newCol = {//create column group
title: oldRow.title,
field: oldRow.field,
columns: [
{
title: rowData.select1.title, field: rowData.select2.name, editor: 'select',
editorParams: {values: rowData.select1.values}
},
{
title: rowData.select2.title, field: rowData.select2.name, editor: 'select',
editorParams: function (cell) {
console.log(cell)
return {values: [1, 2, 3]}
}
},
],
}
From above I need select1 selected value.
Would this work Editors?:
"If you want to generate the options when the select editor is triggered, then you can pass a function into the editorParams, that must return the option list in one of the two formats outlined above"
{title:"Name", field:"name", editor:"select", editorParams:function(cell){
//create a options list of all values from another column in the table
var rows = table.getRows();
var values = {};
rows.forEach(function(row){
var data = row.getData();
values[data.fullname] = data.fullname;
});
return {values:values};
}
Instead of fetching the all the rows, just fetch the cell value of the previous select column and use that to build the choices for the current select. This sort of depends on the specifics of how the two columns relate to each other. More information on that would be helpful.

SuiteScript2.0 Getting values from a saved search formula column

I am trying to get the value from a formula field in a saved search. I am getting all the results and then looping through them as such.
for(key in itemReplenishResults){
log.debug("Single Data", JSON.stringify(itemReplenishResults[key]));
var thisNumber = Number(itemReplenishResults[key].getValue("formulanumeric_1"))
}
The log for the single data read as I would expect;
{
"recordType": "inventoryitem",
"id": "2131",
"values": {
"itemid": "ITEMCODE",
"displayname": "DISPLAYNAME",
"salesdescription": "SALESDESCRIPTION",
"type": [
{
"value": "InvtPart",
"text": "Inventory Item"
}
],
"location": [],
"locationquantityonhand": "",
"locationreorderpoint": "0",
"locationpreferredstocklevel": "1",
"formulatext": "Yes",
"formulanumeric": "1",
"locationquantityonorder": "",
"formulanumeric_1": "1",
"formulatext_1": "Yes"
}
}
But the value of thisNumber is returned as 0. I do not understand why this is not working?
The reason thisNumber is 0 is because the column formulanumeric_1 actually doesn't exist, so Number() is converting a null value to 0.
The problem
Formula columns are all named the same internally, which is why you can't directly get their values individually. For instance, if you have two Formula (Numeric) columns in your search, both internal column names will be "formulanumeric". Therefore, using getValue('formulanumeric') will get only the first formula value.
Logging a Result object will output the incorrect names as you have seen. If you log Result.columns you will see that the column names are actually the same.
Your choices
Directly get columns using indexes (if you care about ordering).
require(['N/search'], function(search) {
// A saved search containing multiple formula result columns
var s = search.load(1234);
s.run().each(function(result) {
log.debug(result.getValue(result.columns[5]));
log.debug(result.getValue(result.columns[1]));
log.debug(result.getValue(result.columns[3]));
});
});
Loop through each column (if you don't care about ordering).
require(['N/search'], function(search) {
// A saved search containing multiple formula result columns
var s = search.load(1234);
s.run().each(function(result) {
for (var i = 0; i < result.columns.length; i++) {
// Log each column's value in order
log.debug(result.getValue(result.columns[i]));
}
});
});
Manually define columns and reference them (the most versatile option). Column names must start with "formula[type]" and can be appended with anything else.
require(['N/search'], function(search) {
var s = search.create({
type: 'salesorder',
columns: [{
name: 'formulanumeric1',
formula: 'CASE WHEN 100 > 10 THEN 100 END'
}, {
name: 'formulanumeric2',
formula: 'CASE WHEN 30 > 20 THEN 30 END'
}]
});
s.run().each(function(result) {
log.debug(result.getValue('formulanumeric2')); // 30
log.debug(result.getValue('formulanumeric1')); // 100
});
});
NOTE: If you go with the first option, you'll have to be careful about reordering the columns in your initial search, as that will affect the indexing in the results.
When I'm working with formula fields, I always use the column index values. An example of one that I have is below. This matches up with the fifth column I created (starting at 0, of course). Hope that helps.
transactionSearch.run().each(function(r){
var var1=r.getValue(r.columns[5]);
var var2=r.getValue(r.columns[6]);
var var3=r.getValue(r.columns[7]);
var var4=r.getValue(r.columns[8]);
var var5=r.getValue(r.columns[9]);
return true;
});

React-Bootstrap-Table-Next Only One Row of Data in Table

I am trying to create a table for my website and for some reason it is only showing the first row of data.
This is how I am formatting the columns of the data:
const { items } = this.props.item;
// console.log({ items });
// react - bootstrap - table - next
const columns = [{
dataField: 'team',
text: 'Team',
sort: true,
formatter: (cellContent, row, rowIndex) => (
Object.values(row.team)[rowIndex]
)
}, {
dataField: 'current_Rank',
text: 'Current Rank',
sort: true,
formatter: (cellContent, row, rowIndex) => (
Object.values(row.current_Rank)[rowIndex]
)
}, {
dataField: 'new_Rank',
text: '321 Rank',
sort: true,
formatter: (cellContent, row, rowIndex) => (
Object.values(row.new_Rank)[rowIndex]
)
}];
This is how I am returning the table so that it renders the table:
return (
<BootstrapTable
keyField="team"
data={items}
columns={columns}
striped
hover />
)
}
}
The data:
Picture from the console
Live site: https://nhl-321-pointsystem.herokuapp.com/
I looked up your network response for /api/items API call, and found out that the data contains only one item. This being one of the reason you're seeing a single row when the table is rendered.
Please note the, another reason for the issue is, react-bootstrap-table-next key
data accepts a single Array object. And not array of single object.
You should re-arrange your data so that key 'team' will be present for all items in the array. And rest of the column header values (e.g. current_Rank) are available for each like.
Something like a reformat function I created in the sandbox available here.
Plus point - After you apply the reformat function, you won't need formatter for each column unlike your previous solution.
Alternate but recommended solution would be to send the formatted response from the API endpoint only, instead of re-parsing and creating new object to fit the needs of UI.
Sandbox link - https://codesandbox.io/embed/32vl4x4oj6

How do I get json data with retrhinkdb

(I'm not good eng.)
I use a group to include dates. I want to get the information out in a row. What do i need to do
.group(r.row('time_create').dayOfWeek())
json export
[
{
group: 1,
reduction: [
{
detail: "no",
id: "37751c10-97ea-4a3a-b2c9-3e8b39383b79",
order_id: "15",
status: "Not_Delivery",
time_create: "2018-09-23T15:25:13.141Z"
}
]
}
]
i want change data json to
{
"date":
{
"Sun": [
{
detail: "no",
order_id: "15",
status: "Not_Delivery",
time_create: "2018-09-28 15:25:13"
}
]
}
}
Do i have to give the information out as i want.
Looks like you tried but didn't manage to transform the data from your previous question. ;)
Here is a proposition, this is not the only way of doing it.
First, it seems you want to remove the id field. You may do that in your ReQL using without:
.group(r.row('time_create').dayOfWeek()).without('id')
(You may apply without('id') before group, it should work the same, see this for more details.)
Then, to transform the result array (let's call it queryResult) into an object (let's call it output):
// prepare the skeleton of the output
let output = {
date: {}
};
// walk the result, filling the output in the process
queryResult.forEach((groupData) => {
let key = groupData.group;
if (!output[key]) {
output[key] = [];
}
output.date[key].push(...groupData.reduction);
})
Now you almost have your desired structure in output, the only thing is that day keys are still numbers and not a short day name. In my opinion, this should be handled by the front-end, since you may want to have different languages implemented for your front-end. But anyway, the idea is always the same: having a translation table that maps Rethink's day numbers with human-readable day names:
const translationTable = {
1: 'Mon',
2: 'Tue',
// ...
7: 'Sun'
};
Now if you do that in your front-end, you just replace the data's keys on the fly, when displaying is needed (or retrieve the key from the day name, depending on how you display stuff). Otherwise, if you go for a back-end implementation (which, again, is clearly not the best solution), you can change one line in the code above (assuming you declared translationTable already):
let key = groupData.group;
// becomes
let key = translationTable[groupData.group];
Feel free to ask in comments if there's something you don't understand!

Resources