// Okay originally people do their IDs for stuff like this:
var Item1 = 0;
var Item2 = 1;
var Item3 = 2;
var Item4 = 3;
var Item5 = 4;
// ... and so on.
// Then create more variables for their checks like:
var HasItem1 = false;
var HasItem2 = false;
var HasItem3 = false;
var HasItem4 = false;
var HasItem5 = false;
// Then somewhere in their code set the items to true if they want the user or player to // have the item, but that's alot of variables.
// Instead I wanted to do something like this:
var Item1 = 1;
var Item2 = 2;
var Item3 = 4;
var Item4 = 8;
var Item5 = 16;
var HasItems = 0; // 0 = no items added.
// The somewhere in my code:
HasItems = Item1 + Item3 + Item4; // 1 + 4 + 8 = 13
// But can't find a way to check if the player has Item3 for example.
if(HasItems != 0 && (HasItems & Item3) != -1) { // It was something like this.
// Has the item we're looking for.
}
// Seen the ID system I'm talking about before, I forget where.
// Anyone know about this system of IDs?
// !!!EDIT!!!
http://blog.millermedeiros.com/using-integers-to-store-multiple-boolean-values/
Example:
[code]
var Item1 = (1 << 1);
var Item2 = (1 << 2);
var Item3 = (1 << 3);
var Item4 = (1 << 4);
var Item5 = (1 << 5);
var Items = (Item1 | Item3 | Item4);
if(Items & Item1) {
print("true 1");
}
else {
print("false 1");
}
if(Items & Item2) {
print("true 2");
}
else {
print("false 2");
}
if(Items & Item3) {
print("true 3");
}
else {
print("false 3");
}
if(Items & Item4) {
print("true 4");
}
else {
print("false 4");
}
if(Items & Item5) {
print("true 5");
}
else {
print("false 5");
}
[/code]
Output:
true 1
false 2
true 3
true 4
false 5
Thank you all for your responses, I searched bitwise and walla.
Special thanks to winterblood!
For your concern, I know it only supports a limited amount of values, this is meant for small systems.
Checking for 1 bit can be done with the following code:
(HasItems & (1 << itemNumber)) != 0
where itemNumber is number of item, starting at 0.
Also, this may be more universal and convenient:
http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx
http://msdn.microsoft.com/en-us/library/system.collections.specialized.bitvector32.aspx
Related
I'm trying to pull data from my YouTube channel, numbers of views, etc, into a Google sheet.
I authorized YouTube APIs, but it cannot retrieve my youtube channel ID.
Here's the error message:
Invalid number of arguments provided. Expected 0-1 only (line 31, file "Code")
line 31 is : var analyticsResponse = YouTubeAnalytics.Reports.query(
I'm using a script found online:
function testingYTpage() {
var url = "https://www.youtube.com/watch?v=ua4QGWmDfB8&list=PLOU2XLYxmsILvfJcIASBDbgfxloFz_XsU&index=7";
var rawData = UrlFetchApp.fetch(url).getContentText();
Logger.log(rawData);
}
//
//
//
function spreadsheetAnalytics() {
// Get the channel ID
var myChannels = YouTube.Channels.list('id', {mine: true});
var channel = myChannels.items[0];
var channelId = channel.id;
// Set the dates for our report
var today = new Date();
var monthAgo12 = new Date();
monthAgo12.setMonth(today.getMonth() - 11);
var todayFormatted = Utilities.formatDate(today, 'UTC', 'yyyy-MM-dd')
var oneMonthAgoFormatted = Utilities.formatDate(monthAgo12, 'UTC', 'yyyy-MM-dd');
// The YouTubeAnalytics.Reports.query() function has four required parameters and one optional
// parameter. The first parameter identifies the channel or content owner for which you are
// retrieving data. The second and third parameters specify the start and end dates for the
// report, respectively. The fourth parameter identifies the metrics that you are retrieving.
// The fifth parameter is an object that contains any additional optional parameters
// (dimensions, filters, sort, etc.) that you want to set.
var analyticsResponse = YouTubeAnalytics.Reports.query(
'channel==' + channelId,
oneMonthAgoFormatted,
todayFormatted,
// dimensions=day metrics=views,estimatedMinutesWatched,averageViewDuration,averageViewPercentage,subscribersGained
'views,estimatedMinutesWatched,averageViewDuration,averageViewPercentage,likes,dislikes,shares',
{
dimensions: 'day',
sort: '-day'
});
// Create a new Spreadsheet with rows and columns corresponding to our dates
var ssName = 'YouTube channel report ' + oneMonthAgoFormatted + ' - ' + todayFormatted;
var numRows = analyticsResponse.rows.length;
var numCols = analyticsResponse.columnHeaders.length;
// Add an extra row for column headers
var ssNew = SpreadsheetApp.create(ssName, numRows + 1, numCols);
// Get the first sheet
var sheet = ssNew.getSheets()[0];
// Get the range for the title columns
// Remember, spreadsheets are 1-indexed, whereas arrays are 0-indexed
var headersRange = sheet.getRange(1, 1, 1, numCols);
var headers = [];
// These column headers will correspond with the metrics requested
// in the initial call: views, likes, dislikes, shares
for(var i in analyticsResponse.columnHeaders) {
var columnHeader = analyticsResponse.columnHeaders[i];
var columnName = columnHeader.name;
headers[i] = columnName;
}
// This takes a 2 dimensional array
headersRange.setValues([headers]);
// Bold and freeze the column names
headersRange.setFontWeight('bold');
sheet.setFrozenRows(1);
// Get the data range and set the values
var dataRange = sheet.getRange(2, 1, numRows, numCols);
dataRange.setValues(analyticsResponse.rows);
// Bold and freeze the dates
var dateHeaders = sheet.getRange(1, 1, numRows, 1);
dateHeaders.setFontWeight('bold');
sheet.setFrozenColumns(1);
// Include the headers in our range. The headers are used
// to label the axes
var range = sheet.getRange(1, 1, numRows, numCols);
var chart = sheet.newChart()
.asColumnChart()
.setStacked()
.addRange(range)
.setPosition(4, 2, 10, 10)
.build();
sheet.insertChart(chart);
}
//
// A Helper function to extract the ID of our video
// It works both on version of links:
// 1. https://www.youtube.com/watch?v=BuHEhmp47VE
// 2. http://youtu.be/BuHEhmp47VE
//
function extractVideoID() {
var curSheet = SpreadsheetApp.getActiveSheet();
var ytLinks = curSheet.getRange("D:D");
var totalRows = ytLinks.getNumRows();
var ytVal = ytLinks.getValues();
// let's run on the rows
for (var i = 1; i <= totalRows - 1; i++) {
var curLink = ytVal[i][0];
if (curLink == "") {
break;
}
var videoID = "";
var inx1 = curLink.indexOf('watch?v=') + 8;
if (inx1 == 7) {
// check if it's the short format: http://youtu.be/75EuHl6CSTo
if (curLink != "" && curLink.indexOf("youtu.be") > 0) {
videoID = curLink.substr(16, curLink.length);
}
}
else {
// we have the link in this format: https://www.youtube.com/watch?v=YIgSucMNFAo
var inx2 = curLink.indexOf("&", inx1);
if (inx2 > inx1) {
videoID = curLink.substr(inx1, inx2-inx1);
} else {
videoID = curLink.substr(inx1, curLink.length);
}
}
curSheet.getRange("E" + (i+1)).setValue(videoID);
}
var htmlMsg = HtmlService
.createHtmlOutput('<h3>Done - Please check the IDs on Column D:D</h3>').setTitle('YT Dashboard Example').setWidth(450).setHeight(300);
SpreadsheetApp.getActiveSpreadsheet().show(htmlMsg);
}
//
// Run on all the rows and according to the video ID fetch the feed
//
function fetchAllData() {
var start = new Date().getTime();
var curSheet = SpreadsheetApp.getActiveSheet();
var ytIds = curSheet.getRange("E:E");
var totalRows = ytIds.getNumRows();
var ytVal = ytIds.getValues();
var errMsg = "<h4>Errors:</h4> <ul>";
// let's run on the rows after the header row
for (var i = 1; i <= totalRows - 1; i++) {
// e.g. for a call: https://gdata.youtube.com/feeds/api/videos/YIgSucMNFAo?v=2&prettyprint=true
if (ytVal[i] == "") {
Logger.log("We stopped at row: " + (i+1));
break;
}
var link = "https://gdata.youtube.com/feeds/api/videos/" + ytVal[i] + "?v=2&prettyprint=true";
try {
fetchYTdata(link, i+1);
}
catch (err) {
errMsg += "<li>Line: " + i + " we could not fetch data for ID: " + ytVal[i] + "</li>";
Logger.log("*** ERR: We have issue with " + ytVal[i] + " On line: " + i);
}
}
if (errMsg.length < 24) {
// we do not have any errors at this run
errMsg += "<li> All good for now </li>";
}
var end = new Date().getTime();
var execTime = (end - start) / 1000;
var htmlApp = HtmlService
.createHtmlOutput('<h2>Done updating!</h2><p>It took us: '+ execTime + 'sec. to update: ' +
(i+1) + ' videos</p>' + errMsg).setTitle('YT Stats').setWidth(450).setHeight(450);
SpreadsheetApp.getActiveSpreadsheet().show(htmlApp);
}
//
// Read YT stats data on our videos and fill the sheet with the data
//
function fetchYTdata(url, curRow) {
//var url = 'https://gdata.youtube.com/feeds/api/videos/Eb7rzMxHyOk?v=2&prettyprint=true';
var rawData = UrlFetchApp.fetch(url).getContentText();
//Logger.log(rawData);
// published <published>2014-05-09T06:22:52.000Z</published>
var inx1 = rawData.indexOf('published>') + 10;
var inx2 = rawData.indexOf("T", inx1);
var publishedDate = rawData.substr(inx1, inx2-inx1);
// viewCount='16592'
var inx1 = rawData.indexOf('viewCount') + 11;
var inx2 = rawData.indexOf("'/>", inx1);
var totalViews = rawData.substr(inx1, inx2-inx1);
// <yt:duration seconds='100'/>
var inx1 = rawData.indexOf('duration seconds') + 18;
var inx2 = rawData.indexOf("'/>", inx1);
var durationSec = rawData.substr(inx1, inx2-inx1);
Logger.log(curRow + ") TotalViews: " + totalViews + " durationSec: " + durationSec);
// update the sheet
var ss = SpreadsheetApp.getActiveSheet();
ss.getRange("C" + curRow).setValue(publishedDate);
ss.getRange("G" + curRow).setValue(totalViews);
ss.getRange("H" + curRow).setValue(durationSec);
}
//
// Our custom menu
//
function onOpen() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{ name : "Update Stats", functionName : "fetchAllData"},
{ name : "Extract Video IDs", functionName : "extractVideoID"}
];
spreadsheet.addMenu("YT Dashboard", entries);
};
non-scripted non-API solution (for meanwhile):
CHANNEL ID:
=ARRAYFORMULA(REGEXREPLACE(QUERY(SUBSTITUTE(ARRAY_CONSTRAIN(
IMPORTDATA(https://www.youtube.com/watch?v=rckrnYw5sOA), 3000, 1), """", ""),
"where Col1 contains '<meta itemprop=channelId content='"),
"<meta itemprop=channelId content=|>", ""))
VIEWS:
=VALUE(REGEXREPLACE(TEXT(IMPORTXML("https://www.youtube.com/watch?v=MkgR0SxmMKo",
"//*[contains(#class, 'watch-view-count')]"),0)," view(s)?",""))
MORE: https://stackoverflow.com/a/55064665/5632629
I also faced the same issue. Used the below syntax for the Reports.query method and got it worked.
YouTubeAnalytics.Reports.query({
ids: 'channel==' + channelId,
startDate: formatDateString(lastMonth),
endDate: formatDateString(today),
metrics: metrics.join(','),
dimensions: 'day',
sort: 'day'
});
I'm trying to make a google spreadsheet script.
When the value of a cell changes to a specified value I want it to trigger hide/unhide rows.
Here is my script so far:
function autoHide() {
var ss = SpreadsheetApp.getActive()
var sheet = SpreadsheetApp.getActiveSheet()
var cell = ss.getActiveCell()
var cell1 = ("C12");
if (cell1 == "Others" ) {
ss.getActiveSheet().showRows(14, 3);
}
else if (cell1 == "Additional Discount/s (over and above 25%)" ) {
ss.getActiveSheet().showRows(17, 4);
}
else {
ss.getActiveSheet().hideRows(14, 7)
}
}
Your question is a little unclear about some points so I assumed you wanted to track the value of cell C12 when C12 is edited.
function autoHide() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var cell = ss.getActiveCell();
var value = cell.getValue();
var cellRef = cell.getA1Notation();
if (cellRef !== "C12") return;
// This isn't the cell we are looking for, stop executing the function.
if (value === "Others" ) {
sheet.showRows(14, 3);
} else if (value === "Additional Discount/s (over and above 25%)" ) {
sheet.showRows(17, 4);
} else {
sheet.hideRows(14, 7);
}
}
If you want to run the function anytime any cell is edited, use this code.
Useful if C12 is a formula and is not updated manually.
function autoHide() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var cellRef = "C12";
var cell = sheet.getRange(cellRef);
var value = cell.getValue();
if (value === "Others" ) {
sheet.showRows(14, 3);
} else if (value === "Additional Discount/s (over and above 25%)" ) {
sheet.showRows(17, 4);
} else {
sheet.hideRows(14, 7);
}
}
Setting colors of cells 1 by 1 is extremely slow. It is advised to do that by assigning an array to the range. I read about that and there is often refered to the following sample. However I can't get this to work so it doesn't help me.
var cell = sheet.getRange('a1');
var colors = new Array(100);
for (var y = 0; y < 100; y++) {
xcoord = xmin;
colors[y] = new Array(100);
for (var x = 0; x < 100; x++) {
colors[y][x] = getColorFromCoordinates(xcoord, ycoord);
xcoord += xincrement;
}
ycoord -= yincrement;
}
sheet.getRange(1, 1, 100, 100).setBackgroundColors(colors);
My piece of code is the following and ends with the message (error): Cannot convert array to object[[]], pointing at the last line.
function TabelMarkeren() {
var selection = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef") // 6 by 3;
var colors = [];
for (var row = 1; row <= selection.getNumRows(); ++row) {
var cell = selection.getCell(row, 1);
if (cell.isBlank()) {
colors[row, 1] = "#86d8b6";
}// if
else {
colors[row, 1] = "c4c4a4";
}// else
colors[row, 2] = "blue";
colors[row, 3] = "green";
}// for
SpreadsheetApp.getActiveSpreadsheet().
getRangeByName("Proef").setBackgrounds(colors);
}
When I use a Browser.msgBox . . to show me some values from the array. It is ok. But clearly setBackgroundColors wants an object and not an array.
The setBackgrounds expect the value in [][] and you are passing the values in []. Refer the below code.
function TabelMarkeren() {
var selection = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef") // 6 by 3;
var finalColors = [];
for (var row = 1; row <= selection.getNumRows(); ++row) {
var colors = [];
var cell = selection.getCell(row, 1);
if (cell.isBlank()) {
colors[row, 1] = "#86d8b6";
} // if
else {
colors[row, 1] = "c4c4a4";
} // else
colors[row, 2] = "blue";
colors[row, 3] = "green";
finalColors.push(colors)
} // for
Logger.log(colors)
SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef").setBackgrounds(finalColors);
}
Thank you Ritz, I have it working now.
I also had to change the colomn indexes from 1,2,3 to 0,1,2. That was another mistake. The code is now:
function TabelMarkerenn() {
var selection = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef");
var finalColors = []
for (var row = 1; row <= selection.getNumRows(); ++row) {
var colors = [];
var cell = selection.getCell(row, 1);
if (cell.isBlank()) {
colors[row, 0] = "#86d8b6";
}// if
else {
colors[row, 0] = "#c4c4a4";
}// else
colors[row, 1] = "blue";
colors[row, 2] = "green";
finalColors.push(colors);
}// for
Logger.log(finalColors);
SpreadsheetApp.getActiveSpreadsheet().
getRangeByName("Proef").setBackgrounds(finalColors);
}
Very happy with this, but . . . isn't there a way to directly use the finalColors array? Or is that slower or just not common practice.
Can any1 explain how we can create Excel WITHOUT using INTEROP in c# window service.
So that I can apply styles also to the generating excel as I wish.
Rigin
You can use one of the Excel libraries. I use this C# Excel library.
See also this sample of code:
http://www.easyxls.com/manual/FAQ/export-to-excel-in-dot-net.html
You can create both XLS or XLSX documents.
You can create excel in windows services like below:
public static void GenerateExcel(DataTable DT, string fullFileName, string rptHeader, string SheetName)
{
try
{
var file = new FileInfo(fullFileName);
string currentFileName = System.IO.Path.GetFileName(fullFileName);
ExcelPackage excel = new ExcelPackage(file);
var sheetcreate = excel.Workbook.Worksheets.Add("Sheet1");
//rptHeader = getCaption(rptHeader);
char c = 'A';
c = (char)(((int)c) + DT.Columns.Count - 1);
//sheetcreate.Cells["A1:" + c+"1"].Value = rptHeader;
sheetcreate.Cells["A1:D1"].Value = rptHeader;
sheetcreate.Cells["A1:" + c + "1"].Style.Fill.PatternType = ExcelFillStyle.Solid;
//sheetcreate.Cells["A1:" + c + "1"].Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#c6c6c6"));
sheetcreate.Cells[1, 1, 1, DT.Columns.Count].Merge = true;
sheetcreate.Cells[1, 1, 1, DT.Columns.Count].Style.Font.Bold = true;
int col = 0;
foreach (DataColumn column in DT.Columns)
{
sheetcreate.Cells[2, ++col].Value = column.ColumnName;
sheetcreate.Cells[2, col].Style.Font.Bold = true;
sheetcreate.Cells[2, col].Style.Border.BorderAround(OfficeOpenXml.Style.ExcelBorderStyle.Thin);
sheetcreate.Cells[2, col].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
}
if (DT.Rows.Count > 0)
{
int row = 2;
for (int eachRow = 0; eachRow < DT.Rows.Count; ) //looping each row
{
bool havingText = false;
for (int eachColumn = 1; eachColumn <= col; eachColumn++) //looping each column in a row
{
var eachRowObject = sheetcreate.Cells[row + 1, eachColumn];
eachRowObject.Style.Fill.PatternType = ExcelFillStyle.Solid;
eachRowObject.Value = DT.Rows[eachRow][(eachColumn - 1)].ToString();
if (!havingText) //checking if 'totoa' in string and setting up 'havingText' variable to color it differently
havingText = DT.Rows[eachRow][(eachColumn - 1)].ToString().ToLower().Contains("total");
//Making all cell value to left align
eachRowObject.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
//if (CL.isDecimal(DT.Rows[eachRow][(eachColumn - 1)].ToString())) //if it is number with decimal value make it right align
//{
// eachRowObject.Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;
//}
//eachRowObject.Style.Border.BorderAround(OfficeOpenXml.Style.ExcelBorderStyle.Thin); // adding border to each cells
//if (eachRow % 2 == 0) //alternatively adding color to each cell.
// eachRowObject.Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#e0e0e0"));
//else
// eachRowObject.Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#ffffff"));
}
if (havingText) //if any cell data containt 'total' color complete.
{
for (int eachColumn = 1; eachColumn <= col; eachColumn++)
{
sheetcreate.Cells[row + 1, eachColumn].Style.Fill.PatternType = ExcelFillStyle.Solid;
//sheetcreate.Cells[row + 1, eachColumn].Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#86a9ef"));
}
}
eachRow++;
row++;
}
getLog("batch controller: in loop");
}
getLog("batch controller: 485");
sheetcreate.Cells.AutoFitColumns();
excel.Save();
}
catch (Exception e)
{
getLog("Error while generating excel=>"+e);
}
}
You can download EPPlus from : https://www.nuget.org/packages/EPPlus/
I need to format numbers with commas as thousand seperators, for example:
1234 = 1,234
1234.50 = 1,234.50
12345.60 = 12,345.60
123456.70 = 123,456.70
1234567.80 = 1,234,567.80
etc etc
This needs to work for numbers with decimal values or without
i.e. both 1234567.80 and 1234567
This is for Actionscript 2 in a Coldfusion / Flash application, so normal actionscript is being used. I have seen a couple of solutions on the net but none quite do the trick.
So far I have the function below, but it is not formatting correctly when decimals are provided.For example: 21898.5 becomes 2,188,8.5.
Please could you help me find the bug or offer an alternative solution that fulfils the requriements.
Thanks
_global.NumberFormat = function(theNumber)
{
var myArray:Array;
var numberPart:String;
var decPart:String;
var result:String = '';
var numString:String = theNumber.toString();
if(theNumber.indexOf('.') > 0)
{
myArray = theNumber.split('.');
numberPart = myArray[0];
decPart = myArray[1];
}
else
{
numberPart = numString;
}
while (numString.length > 3)
{
var chunk:String = numString.substr(-3);
numString = numString.substr(0, numString.length - 3);
result = ',' + chunk + result;
}
if (numString.length > 0)
{
result = numString + result;
}
if(theNumber.indexOf('.') > 0)
{
result = result + '.' + decPart;
}
//alert('Result: ' + result);
return result;
}
You could try this:
_global.NumberFormat = function(numString)
{
numString = String(numString);
var index:Number = numString.indexOf('.');
var decimal:String;
if(index > 0) {
var splitByDecimal:Array = numString.split(".");
//return NumberFormat(splitByDecimal[0])+"."+splitByDecimal[1];
numString = splitByDecimal[0];
decimal = splitByDecimal[1];
} else if(index === 0) {
return "0"+numString;
}
var result:String = '';
while (numString.length > 3 ) {
var chunk:String = numString.substr(-3);
numString = numString.substr(0, numString.length - 3);
result = ',' + chunk + result;
}
result = numString + result;
if(decimal) result = result + "." + decimal;
return result;
}
It splits the number by the decimal if present(compensating for an illegal '.01234' if required), and uses recursion so call itself on the split element.
For your example numbers this traces:
1,234
1,234.50
12,345.60
123,456.70
1,234,567.80
Just for fun
This is why your original code didn't work:
After creating a string representation of the number (var numString:String = theNumber.toString();) you then carried on using the actual number rather than the string version.
After assigning a value to number part you then continued to perform operations on numString rather than numberPart.
A corrected version looks like this:
_global.NumberFormat = function(theNumber)
{
var myArray:Array;
var numberPart:String;
var decPart:String;
var result:String = '';
var numString:String = theNumber.toString();
if(numString.indexOf('.') > 0)
{
myArray = numString.split('.');
numberPart = myArray[0];
decPart = myArray[1];
}
else
{
numberPart = numString;
}
while (numberPart.length > 3)
{
var chunk:String = numberPart.substr(-3);
numberPart = numberPart.substr(0, numberPart.length - 3);
result = ',' + chunk + result;
}
if (numberPart.length > 0)
{
result = numberPart + result;
}
if(numString.indexOf('.') > 0)
{
result = result + '.' + decPart;
}
//alert('Result: ' + result);
return result;
}
public static function formatNumberString(value:Number,separator:String):String {
var result:String = "";
var digitsCount:Number = value.toString().length;
separator = separator || ",";
for (var i:Number = 0; i < digitsCount; i++) {
if ((digitsCount - i) % 3 == 0 && i != 0) {
result += separator;
}
result += value.toString().charAt(i);
}
return result;
}
Try this out, works fine for me:
var largeNumber:String=new String(1000000.999777);
var fAr:Array=largeNumber.split(".");
var reg:RegExp=/\d{1,3}(?=(\d{3})+(?!\d))/;
while(reg.test(fAr[0]))
fAr[0]=fAr[0].replace(reg,"$&,");
var res:String=fAr.join(".");
trace(res);
Trace: 1,000,000.999777