For statistical reasons, I want an extensive analysis from a dataset. I already have a function that exports the data to Excel, but I have raw data that way; 500 lines, 35 columns, heaps of text sometimes...
Is it possible to include a macro into a function so that the excelfile is readymade to be analyzed?
I am using ASP, Javascript, and at the moment Excel 2003.
This is the current function (written by one of my predecessors):
function exporttoexcel()
{ //export to excel
if (tableSortArray.length > 0)
{
var t, arr;
var tempArray=new Array();
for(var i=0; i, i<tableSortArray.length; i++) {
arr = tableSortArray[i].toString();
arrr = (arr.split(","));
if (i==0) { t = arrr[1]; }
else { t += ','+arrr[1]; }
}
document.excel.t.value = t;
}
// I left out some mumbojumbo about sorting here
document.excel.submit();
}
I mean macro's so that graphs are made "automatically" as well as some turntables...
Stolen from mrexcel.com (google + cut_paste = faster than typing):
' Delete any old stray copies of the module1
On Error Resume Next
Kill ("C:\MrXL1.bas")
On Error GoTo 0
' Export Module 1
ActiveWorkbook.VBProject.VBComponents("module1").Export ("c:\MrXL1.bas")
For x = 1 to 54
ThisBroker = Sheets("BrokerList").range("A" & x).value
' customization of plan omited for brevity
Sheets(Array("Menu", "Plan")).Copy
NBName = ActiveWorkbook.Name
' new book name
' Import Module 1 to this new book
Application.VBE.ActiveVBProject.VBComponents.Import ("c:\MrXL1.bas")
ActiveWorkbook.SaveAs Filename:=ThisBroker
ActiveWorkbook.Close
Next x
Kill ("C:\MrXl1.bas")
Alternatively you could also just setup a master excel file (say called "analysis.xls") that references the data in the "data" excel file, for example in a cell enter:
='Z:\excel-data[Current-data.xls]Sheet1'!$A$1
User opens up the master ("analysis.xls") and it in turn adds all the values from Z:\excel-data\Current-data.xls, just replace Current-data.xls with new data as needed.
Related
I am looking to update a numeric field for multiple records with arithmetic, not just overriding the current value with a new one. To do this, I plan on uploading a file with the identifier of the item and the new value being added. Parse the file and use custom searches to find the corresponding records, then loading, updating and saving the proper record. However, how to run the script is where I get confused.
I have created previous scripts beforeLoad scripts which run on entering the edit view of an item, but I have not used any server side scripts yet (I read that when accessing files from the filing cabinet, you must use a server side script).
Any information about server script types and when to use them would be appreciated. Thank you.
For this sort of thing a Map/Reduce script is your best bet
You can pass a fileId as a parameter and your getInputData stage can just load and return the file(which, IIRC, sends each line to your map stage). Your map stage has to ignore the header, if present, and any trailing bad lines.
I havent' been able to easily find a script that I've written that does that but I'm pretty sure I have done that.
Normally though I do something like this for processing a file into the map stage:
function getInputData(){
try{
var me = runtime.getCurrentScript();
var targetFileId = <number>me.getParameter({name:'custscript_kotn_att_emp_file'});
var targetFile = file.load({id:targetFileId});
log.audit({title: 'getting data', details:targetFile.name +' ' + targetFile.size});
var empLines = [];
targetFile.lines.iterator().each(line=>{
var parts = line.value.split('|');
if(parts.length >2 && parts.length != expectColumns.length){
throw new Error('Unexpected line length. Had '+ parts.length +' expected '+ expectColumns.length);
}
if(parts.length > 2){
empLines.push(parts);
}
return true;
});
log.audit({title: 'got employee lines', details:empLines.length});
return empLines;
}catch(e){
log.error({
title:"in input stage",
details : (e.message || e.toString()) + (e.getStackTrace ? (' \n \n' + e.getStackTrace().join(' \n')) : '')
});
return null;
}
};
function map(ctx){
const empLine = JSON.parse(ctx.value);
//you have an array of the parsed line
}
I'm trying to convert excel sheet contents and functions to my react project.
I've encountered convert FORECAST.ETS and FORECAST.LINEAR to typescript code.
Should I have to create excel file and insert my data to excel and run FORECAST.ETS and FORECAST.LINEAR then crop the value?
Is this the only way to call excel forecast function in javascript?
I was able to use the answer on a prior question to get help with using forecast. It provided a function I was able to use in order to calculate the forecast amount correctly. Maybe it will help you too.
Question/Answer
function forecast(x, ky, kx){
var i=0, nr=0, dr=0,ax=0,ay=0,a=0,b=0;
function average(ar) {
var r=0;
for (i=0;i<ar.length;i++){
r = r+ar[i];
}
return r/ar.length;
}
ax=average(kx);
ay=average(ky);
for (i=0;i<kx.length;i++){
nr = nr + ((kx[i]-ax) * (ky[i]-ay));
dr = dr + ((kx[i]-ax)*(kx[i]-ax))
}
b=nr/dr;
a=ay-b*ax;
return (a+b*x);
}
Example:
forecast(30, [6,7,9,15,21], [20,28,31,38,40] );
Currently it is not possible in confluence to have the headings of the document structure numbered automatically. I am aware that there are (paid) 3rd party plugins available.
How can I achieve continuous numbered headings?
TL;DR
Create a bookmark for the following javascript and click it in edit mode in confluence to renumber your headings.
javascript:(function()%7Bfunction%20addIndex()%20%7Bvar%20indices%20%3D%20%5B%5D%3BjQuery(%22.ak-editor-content-area%20.ProseMirror%22).find(%22h1%2Ch2%2Ch3%2Ch4%2Ch5%2Ch6%22).each(function(i%2Ce)%20%7Bvar%20hIndex%20%3D%20parseInt(this.nodeName.substring(1))%20-%201%3Bif%20(indices.length%20-%201%20%3E%20hIndex)%20%7Bindices%3D%20indices.slice(0%2C%20hIndex%20%2B%201%20)%3B%7Dif%20(indices%5BhIndex%5D%20%3D%3D%20undefined)%20%7Bindices%5BhIndex%5D%20%3D%200%3B%7Dindices%5BhIndex%5D%2B%2B%3BjQuery(this).html(indices.join(%22.%22)%2B%22.%20%22%20%2B%20removeNo(jQuery(this).html()))%3B%7D)%3B%7Dfunction%20removeNo(str)%20%7Blet%20newstr%20%3D%20str.trim()%3Bnewstr%20%3D%20newstr.replace(%2F%5B%5Cu00A0%5Cu1680%E2%80%8B%5Cu180e%5Cu2000-%5Cu2009%5Cu200a%E2%80%8B%5Cu200b%E2%80%8B%5Cu202f%5Cu205f%E2%80%8B%5Cu3000%5D%2Fg%2C'%20')%3Bif(IsNumeric(newstr.substring(0%2Cnewstr.indexOf('%20'))))%7Breturn%20newstr.substring(newstr.indexOf('%20')%2B1).trim()%3B%7Dreturn%20newstr%3B%7Dfunction%20IsNumeric(num)%20%7Bnum%20%3D%20num.split('.').join(%22%22)%3Breturn%20(num%20%3E%3D0%20%7C%7C%20num%20%3C%200)%3B%7DaddIndex()%7D)()
Result
How to use
After changes to the structure have been made, clicking the bookmarked javascript renumbers the document.
Limitations are that it only provides n.n.n. numbering, but for many cases that's sufficient. The script can also be customized as required.
Background, explanation and disclosure
I tried this TaperMonkey script that apparently resulted from this post, but it didn't work as is. So I took its source code and stripped it of the integration code, old version compatibility and made some minor adjustments to get this:
function addIndex() {
var indices = [];
jQuery(".ak-editor-content-area .ProseMirror").find("h1,h2,h3,h4,h5,h6").each(function(i,e) {
var hIndex = parseInt(this.nodeName.substring(1)) - 1;
if (indices.length - 1 > hIndex) {
indices= indices.slice(0, hIndex + 1 );
}
if (indices[hIndex] == undefined) {
indices[hIndex] = 0;
}
indices[hIndex]++;
jQuery(this).html(indices.join(".")+". " + removeNo(jQuery(this).html()));
});
}
function removeNo(str) {
let newstr = str.trim();
newstr = newstr.replace(/[\u00A0\u1680​\u180e\u2000-\u2009\u200a​\u200b​\u202f\u205f​\u3000]/g,' ');
if(IsNumeric(newstr.substring(0,newstr.indexOf(' ')))){
return newstr.substring(newstr.indexOf(' ')+1).trim();
}
return newstr;
}
function IsNumeric(num) {
num = num.split('.').join("");
return (num >=0 || num < 0);
}
addIndex();
(I'm not a JavaScript developer, I'm sure it can be written nicer/better)
Then I used bookmarklet to convert it into the javascript bookmark at the top, which can be clicked to trigger the functionality.
I want to build a custom Google Sheets function via Google Apps Script and I've gotten stuck along the way.
I want to take the text from the first and second column (A1, A2 ...B1, B2 etc..) and return them with custom text, specifically to have them wrapped in tags.
So if in A1 we have "Can of Soda" and in A2 "$0.99", I would like function to return a final string of "Can of Soda " and "$0.99", but individually wrapped into span tags and then concatenated together into one string.
When I look at the Google Scripts log, I can return the the items in each columns as separate logs (although the first column doesn't return the closing tag). The question is how I get them into one string. I also only go through the first row, when I would like that for loop to go through each row.
Here is my log:
[16-05-30 11:32:02:348 EDT] <span>Can of Soda
[16-05-30 11:32:02:349 EDT] <span>0.99</span>
Here's my code as of now:
function weeklyMenu() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
product = Logger.log("<span>" + data[i][0]) + "</span> ";
price = Logger.log("<span>" + data[i][1] + "</span>");
}
}
\\The end goal is to have a string that says "<span>Can of Soda</span> <span>$0.99</span>"
If you really want to do this with a custom function, in C1 enter:
=weeklyMenu(A1,B1)
The code is:
function weeklyMenu(A,B) {
var sheet = SpreadsheetApp.getActiveSheet();
var con="<span>"+A+"</span> <span>"+B+"</span>";
return con
}
You could also just use a formula (again enter in C1):
="<span>"&A1&"</span> <span>"&B1&"</span>"
Either one can be copied down.
I am trying to parse a CSV file I made in Excel. I want to use it to update my Google map. This Google map is in a mobile app that I am developing with Eclipse for Android.
Honestly, I am not sure how to write the JavaScript. Any help will be greatly appreciated. I would be happy to credit your work.
I just want some JavaScript to run when the user hits a button that does the following:
Locates users current location (I have already done this part!)
Locate nearby locations as entered in the .CSV excel file by parsing the .CSV
Display a small link inside every locations notification bubble that says "Navigate" that when the user clicks it, opens google maps app and starts navigating the user to that location from the users current location (Geolocation).
This is the ONLY part I need to finish this application. So once again, any help at all will be greatly appreciated. Thanks everyone!
Honestly, I've been round and round with this problem. The CSV format is not made for easy parsing and even with complicated RegEx it is difficult to parse.
Honestly, the best thing to do is import it into an FormSite or PHPMyAdmin, then re-export the document with a custom separator that is easier to parse than ",". I often use "%%" as the field delimiter and everything works like a charm.
Dont know if this will help but see http://www.randomactsofsentience.com/2012/04/csv-handling-in-javascript.html if it helps...
Additional:
On top of the solution linked to above (my preference) I also used a shed load of stacked regular expressions to token a CSV but it's not as easy to modify for custom error states...
Looks heavy but still only takes milliseconds:
function csvSplit(csv){
csv = csv.replace(/\r\n/g,'\n')
var rows = csv.split("\n");
for (var i=0; i<rows.length; i++){
var row = rows[i];
rows[i] = new Array();
row = row.replace(/&/g, "&");
row = row.replace(/\\\\/g, "\");
row = row.replace(/\\"/g, """);
row = row.replace(/\\'/g, "'");
row = row.replace(/\\,/g, ",");
row = row.replace(/#/g, "#");
row = row.replace(/\?/g, "?");
row = row.replace(/"([^"]*)"/g, "#$1\?");
while (row.match(/#([^\?]*),([^\?]*)\?/)){
row = row.replace(/#([^\?]*),([^\?]*)\?/g, "#$1,$2?");
}
row = row.replace(/[\?#]/g, "");
row = row.replace(/\'([^\']*)\'/g, "#$1\?");
while (row.match(/#([^\?]*),([^\?]*)\?/)){
row = row.replace(/#([^\?]*),([^\?]*)\?/g, "#$1,$2?");
}
row = row.replace(/[\?#]/g, "");
row = row.split(",")
for (var j=0; j<row.length; j++){
col = row[j];
col = col.replace(/?/g, "\?");
col = col.replace(/#/g, "#");
col = col.replace(/,/g, ",");
col = col.replace(/'/g, '\'');
col = col.replace(/"/g, '\"');
col = col.replace(/\/g, '\\');
col = col.replace(/&/g, "&");
row[j]=col;
}
rows[i] = row;
}
return rows;
}
I had this problem which is why I had to come up with this answer, I found on npm a something called masala parser which is indeed a parser combinator. However it didn't run on browsers yet, which is why I am using this fork, the code remains unchanged. Please read it's documentation to understand the Parser-side of the code.
import ('https://cdn.statically.io/gh/kreijstal-contributions/masala-parser/Kreijstal-patch-1/src/lib/index.js').then(({
C,
N,
F,
Streams
}) => {
var CSV = (delimeter, eol) => {
//parses anything beween a string converts "" into "
var innerstring = F.try(C.string('""').returns("\"")).or(C.notChar("\"")).rep().map(a => a.value.join(''));
//allow a string or any token except line delimeter or tabulator delimeter
var attempth = F.try(C.char('"').drop().then(innerstring).then(C.char('"').drop())).or(C.charNotIn(eol[0] + delimeter))
//this is merely just a CSV header entry or the last value of a CSV line (newlines not allowed)
var wordh = attempth.optrep().map(a => (a.value.join('')));
//This parses the whole header
var header = wordh.then(C.char(delimeter).drop().then(wordh).optrep()).map(x => {
x.header = x.value;
return x
})
//allow a string or any token except a tabulator delimeter, the reason why we allow newlines is because we already know how many columns there is, so if there is a newline, it is part of the value.
var attempt = F.try(C.char('"').drop().then(innerstring.opt().map(a=>(a.value.__MASALA_EMPTY__?{value:""}:a))).then(C.char('"').drop())).or(C.notChar(delimeter))
//this is merely just a CSV entry
var word = attempt.optrep().map(a => (a.value[0]?.value??a.value[0]));
//This parses a CSV "line" it will skip newlines if they're enclosed with doublequotation marks
var line = i => C.string(eol).drop().then(word.then(C.char(delimeter).drop().then(word).occurrence(i - 1).then(C.char(delimeter).drop().then(wordh)))).map(a => a.value);
return header.flatMap(a => line(a.header.length - 1).rep().map(b => {
b.header = a.header;
return b
}))
};
var m = {
'tab': '\t',
"comma": ",",
"space": " ",
"semicolon": ";"
}
document.getElementById('button').addEventListener('click', function() {
var val = document.getElementById('csv').value;
var parsedCSV = CSV(m[document.getElementById('delimeter').value], '\n').parse(Streams.ofString(val)).value;
console.log(parsedCSV);
})
})
Type some csv<br>
<textarea id="csv"></textarea>
<label for="delimeter">Choose a delimeter:</label>
<select name="delimeter" id="delimeter">
<option value="comma">,</option>
<option value="tab">\t</option>
<option value="space"> </option>
<option value="semicolon">;</option>
</select>
<button id="button">parse</button>
I would suggest stripping the newlines and the end of the file. Because it might get confused.
This appears to work. You may want to translate the Japanese, but it is very straight-forward to use:
http://code.google.com/p/csvdatajs/