I have a excel like this:
A B C
a1 b1 c1
c2
a2 b2 c3
c4
Now i want to read the data to json string using c# language like this:
"{'a1':{'b1':['c1','c2']},'a2':{'b2':['c3','c4']}}"
I want to do it because i have to to parse this data to json in javascript,
the data i want to have is:
var obj = {
a1:{
b1:[c1,c2]
},
a2:{
b2:[c3,c4]
}}
I have thought,but i have no thinking.
part of my c# code is this:
public string SheetToData(Worksheet worksheet)
{
int rowsCount = worksheet.NotEmptyRowMax;
int columnsCount = worksheet.NotEmptyColumnMax;
if (rowsCount < 1 || columnsCount < 1)
{
return;
}
for (int r = 0; r < rowsCount + 1; r++)
{
var row = worksheet.Rows[r];
for (int c = 0; c < columnsCount + 1; c++)
{
var cell = row[c];
var value = (cell.ValueAsString ?? "").Trim();
}
}
}
Thanks for your help who can help me solve this problem
The row variable is not needed. You can access a cell value through Cells collection:
for (int r = 0; r < rowsCount + 1; r++)
{
for (int c = 0; c < columnsCount + 1; c++)
{
var value = (worksheet.Cells[r,c].Value ?? "").ToString().Trim();
}
}
Related
I'm trying convert one code that it make a sum of cells by color in VBA, but i need to use the same code or action from code in Office Scripts, i dont know how is the structure in this plataform, maybe, can you help me to do it?
the code in VBA is this:
code
Function SumByColor(Cellcolor As Range, RangeSum As Range) As Double
Dim cell As Range
For Each cell In RangeSum
If celda.Interior.ColorIndex = Celdacolor.Cells(1, 1).Interior.ColorIndex Then SumByColor = SumByColor+ cell
Next cell
Set cell = Nothing
End Function
So i need to use this code in office scripts
Here is one way to write your function in OfficeScript and how to call it -
function main(workbook: ExcelScript.Workbook) {
let sheet = workbook.getActiveWorksheet();
console.log (sumByColor(sheet.getRange("E41"), workbook.getSelectedRange()))
}
function sumByColor(cellColor:ExcelScript.Range, rangeSum:ExcelScript.Range):number {
let value = 0;
let rowCount = rangeSum.getRowCount();
let columnCount = rangeSum.getColumnCount();
let colorToCheck = cellColor.getFormat().getFill().getColor();
// loop through each cell in rangeSum
for (let row=0; row<rowCount; row++)
for (let column = 0; column < columnCount; column++)
{
if (rangeSum.getCell(row,column).getFormat().getFill().getColor() == colorToCheck)
value += rangeSum.getCell(row, column).getValue() as number
}
return value;
}
Thanks for your help. My final code is it :
function main(workbook: ExcelScript.Workbook) {
let sheet = workbook.getActiveWorksheet();
var cont = 2;
const celdas = ['B10', 'C10', 'D10', 'E10', 'F10', 'G10', 'H10', 'I10', 'J10', 'K10', 'L10', 'M10'];
celdas.forEach(celda => {
let valCel = celda;
let startingCell = sheet.getRange(valCel);
var ranguito = "O" + cont.toString();
let rangeDataValue = sheet.getRange(ranguito).getValue() as string;
console.log(sumByColor(sheet.getRange("Q3"), sheet.getRange(rangeDataValue), startingCell))
cont = cont + 1;
});
}
function sumByColor(cellColor: ExcelScript.Range, rangeSum: ExcelScript.Range, writeCell: ExcelScript.Range) {
let value = 0;
let rowCount = rangeSum.getRowCount();
let columnCount = rangeSum.getColumnCount();
let colorToCheck = cellColor.getFormat().getFill().getColor();
// loop through each cell in rangeSum
for (let row = 0; row < rowCount; row++)
for (let column = 0; column < columnCount; column++) {
if (rangeSum.getCell(row, column).getFormat().getFill().getColor() == colorToCheck) {
var total = rangeSum.getCell(row, column).getValue() as string;
value = value + parseFloat(total);
}
}
writeCell.setValue(value);
console.log(value)
}
i couldn't ask my question very well. I put here a table that i want to create in google sheet, excel or other. Anyone can help me please?
street name
number
Impasse Malabane
9
Impasse Malabane
Impasse du Puech
Impasse Bimet
Rue Levers
Impasse du Puech
1 bis
9
1 bis
6
26
Rue Levers
26
5
2 bis
2
28
Impasse Bimet
6
8
1
Impasse Bimet
2
8 bis
Impasse Malabane
5
Impasse du Puech
2 bis
Impasse Malabane
8
Impasse Malabane
8 bis
Impasse du Puech
1
Rue Levers
28
In Google Sheets, assuming that your original headers "Street Name" and "Number" are in A1 and B1 (with the data in A2:B), place this in D2:
=ArrayFormula(TRANSPOSE(TRIM({UNIQUE(FILTER(A2:A,A2:A<>"")),TO_TEXT(SPLIT(TRANSPOSE(TRIM(SPLIT(TEXTJOIN("| ",1,{IFERROR(SUBSTITUTE(VLOOKUP(UNIQUE(FILTER(A2:A,A2:A<>""))&TRANSPOSE(UNIQUE(FILTER(B2:B,B2:B<>""))),A2:A&B2:B,1,FALSE),UNIQUE(FILTER(A2:A,A2:A<>"")),"")),SEQUENCE(COUNTA(UNIQUE(FILTER(A2:A,A2:A<>""))),1,1,0)})&"|","| 1|",0,1))),"|"))})))
This one formula will generate all results. As you add new data in A2:B, it will be added without any need to edit the formula.
This should work in Google Apps Script:
function myFunction() {
// initialize
var ss = SpreadsheetApp.getActiveSheet();
var lr = ss.getLastRow();
var values = ss.getRange(2,1,lr-1,2).getValues();
console.log(values.sort());
var result = [];
console.log(result);
var prevCol = '';
// populate array
for (i = 0; i < values.length; i++) {
if (values[i][0] != prevCol) {
result.push([values[i][0], values[i][1]]);
}
else {
result[result.length-1].push(values[i][1]);
}
prevCol = values[i][0];
}
console.log(result);
// transpose array
var newArray = [];
for(var i = 0; i < result.length; i++){
newArray.push([]);
};
for(var i = 0; i < result.length; i++){
for(var j = 0; j < result.length; j++){
newArray[j].push(result[i][j]);
};
};
// write to range
var dest = ss.getRange(2,4,newArray[0].length,newArray.length);
dest.setValues(newArray);
}
It's a little difficult to understand the question, but I think you are trying to convert a 2-column table into a multi-column table with data.
You can do this with an array formula. First, copy all your distinct street names into a single row. In the picture below, this was done in cells F1:I1.
Cell F2 formula:
{=IFERROR(INDEX($B$2:$B$9999, SMALL(IF($F$1=$A$2:$A$9999, ROW($A$2:$A$9999)-ROW($A$2)+1), ROW(1:1))),"")}
You need to press CTRL+SHIFT+ENTER to get those curly brackets to make this an array formula. Drag it down as far as you need, well beyond as many rows as you would expect. It's wrapped in an IFERROR handler to show a blank if no more results are found.
The formulas for the other columns are similar. You just need to change the reference from $F$1 to $G$1 and so on, and also repeat the array trick.
Also, if you have more than 9999 rows, just adjust the end row number in the formula.
This VBA script does it. Assuming your data starts in A1 in Sheet1.
Sub transform()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim first_col As String: first_col = "A"
Dim ws2 As Worksheet
Dim c_last As Range
Dim c As Range
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Dim key As Variant
Dim arr() As String
Set c_last = ws.Cells(ws.Rows.Count, first_col).End(xlUp)
For Each c In ws.Range(first_col & 2, c_last)
If dict.Exists(Trim(c)) Then
dict.Item(Trim(c)) = dict.Item(Trim(c)) & "$" & CStr(c.Offset(, 1))
Else
dict.Item(Trim(c)) = CStr(c.Offset(, 1))
End If
Next
Set ws2 = ws.Parent.Sheets.Add(After:=ws.Parent.Worksheets(ws.Parent.Worksheets.Count))
Set c = ws2.Range("A1")
For Each key In dict.Keys()
c = key
arr = Split(dict.Item(key), "$")
c.Offset(1).Resize(UBound(arr) + 1) = Application.Transpose(arr)
Set c = c.Offset(, 1)
Next
End Sub
Before:
After:
A correction of Carlos' proposal (Google Sheets) :
function myFunction() {
// initialize
var ss = SpreadsheetApp.getActiveSheet();
var lr = ss.getLastRow();
var values = ss.getRange(2,1,lr-1,2).getValues();
values.sort();
var result = [];
var prevCol = '';
// populate array
for (i = 0; i < values.length; i++) {
if (values[i][0] != prevCol) {
result.push([values[i][0], values[i][1]]);
}
else {
result[result.length-1].push(values[i][1]);
}
prevCol = values[i][0];
}
// determine maximum length
var max = 0 ;
for(var i = 0; i < result.length; i++){
max=Math.max(max,result[i].length);
};
// complete the array by replacing null values with an empty string
for (var i = 0; i < result.length; i ++) {
for (var j = 0; j < max; j ++) {
if (result[i][j] == null) {result[i][j] = "";}
}
}
// transpose array
var result = transpose(result);
// write to range
ss.getRange(2,4,result.length,result[0].length).setValues(result);
}
function transpose(a){
return Object.keys(a[0]).map(function (c) { return a.map(function (r) { return r[c]; }); });
}
How to read Column wise values from excel using nodejs(node-xlsx) ? Please advise.
I want to read Col A data, then Col B and so on, if any data exists in other columns, then put data in array.
I am able to read A1, B1, A2, B2... this way but not A1, A2, A3... then B1, B2, B3... etc.
Sample column wise data
I did custom way but not able to go to col C dynamically.
const xlsxfile = require("xlsx");
var arr = [];
const spreadsheet = xlsxfile.readFile('./Code.xlsx');
const sheets = spreadsheet.SheetNames;
console.log('Sheet Names -- ' + sheets);
const firstSheetName = sheets[0];
const firstSheet = spreadsheet.Sheets[firstSheetName];
console.log(firstSheet);
for (z in firstSheet) {
if (z[0] === '!') continue;
//parse out the column, row, and value
var tt = 0;
for (var i = 0; i < z.length; i++) {
if (!isNaN(z[i])) {
tt = i;
break;
}
};
var col = z.substring(0, tt);
var row = parseInt(z.substring(tt));
for (; ; row++) { // looping over all rows in a column
const firstCol = firstSheet[col+''+row];
if (!firstCol) {
break;
}
let value = firstCol.w;
//console.log(value);
if (value)
if (!arr.includes(value))
arr.push(value);
else
continue;
else
break;
}
}
console.log('final array = '+arr);
I somehow achieved my goal in very bad way. In top most loop it's always trying to get A1, B1, C1 like that. But in between I hijacked and looping all rows.
So in that way, I am keeping one track of what's my last column and comparing in next is same column or new column. if same column, I am existing.
But is there any better way to get all values may be in array format column wise?
const xlsxfile = require("xlsx");
var arr = [];
const spreadsheet = xlsxfile.readFile('./Code.xlsx');
const sheets = spreadsheet.SheetNames;
console.log('Sheet Names -- ' + sheets);
const firstSheetName = sheets[0];
const firstSheet = spreadsheet.Sheets[firstSheetName];
console.log(firstSheet);
let earliercol = []; // keeping a track
for (z in firstSheet) {
if (z[0] === '!') continue;
//parse out the column, row, and value
let tt = 0;
for (let i = 0; i < z.length; i++) {
if (!isNaN(z[i])) {
tt = i;
break;
}
};
let col = z.substring(0, tt);
let row = parseInt(z.substring(tt));
if (earliercol.includes(col)) // checking current col already traversed or not
break;
earliercol.push(col); // assigning current col name
//var value = worksheet[z].v;
for (; ; row++) {
//const firstCol = firstSheet['A' + i];
const firstCol = firstSheet[col+''+row];
if (!firstCol) {
break;
}
let value = firstCol.w;
//console.log(value);
if (value)
if (!arr.includes(value))
arr.push(value);
else
continue;
else
break;
}
}
console.log('final array = '+arr);
I want to convert Row[] list into two dimension Array String[][] using Java8 with Spark
Input DataFrame
+-------------------+----+-----+
| attribute|city|cntry|
+-------------------+----+-----+
|LOC1,LOC2,LOC3,LOC4| chn| AU|
| LOC1,LOC4| mdu| PE|
| LOC9,LOC7| sdu| US|
| LOC5,LOC6| fdu| CAN|
+-------------------+----+-----+
Please help me to get expected output.
Unable to get the expected output and getting only last row data is stored.
Using Java8 with Spark
Dataset<Row> df1 = ss.read().option("inferSchema", true).format("json").load("src/main/resources/input.json");
String[][] outputList = new String[100][100];
Row[] colList = (Row[]) df1.collect();
int rowCount = (int) df1.count();
for (Row rw : colList) {
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < rw.size(); j++) {
outputList[i][j] = rw.get(j).toString();
}}}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
System.out.println("outputList[" + i + "][" + j + "]" + outputList[i][j]);
}}
Expected Output should be as below
outputList[0][0]:LOC1,LOC2,LOC3,LOC4
outputList[0][1]:chn
outputList[0][2]:AU
outputList[1][0]:LOC1,LOC4
outputList[1][1]:mdu
outputList[1][2]:PE
outputList[2][0]:LOC9,LOC7
outputList[2][1]:sdu
outputList[2][2]:US
outputList[3][0]:LOC5,LOC6
outputList[3][1]:fdu
outputList[3][2]:CAN
try it
Row[] rows = (Row[]) df.collect();
int cSize = rows[0].size();
int rSize = rows.length;
String[][] outputList = new String[rSize][cSize];
for (int i = 0; i < rSize; i++) {
Row row = rows[i];
for (int j = 0; j < cSize; j++) {
String element = row.get(j).toString();
outputList[i][j] = element;
}
}
The errors I have: don't create excel file just add another Microsoft excel in background process and saveFileDialog crash when I try to change file location:
saveFileDialog1->InitialDirectory = "C:";
saveFileDialog1->Title = "Save as Excel File";
saveFileDialog1->FileName = "";
saveFileDialog1->Filter = "Excel Files(2003)|*.xls|Excel Files(2007)|*.xlsx";
if(saveFileDialog1>ShowDialog()==System::Windows::Forms::DialogResult::OK){
Microsoft::Office::Interop::Excel::Application^ ExcelApp = gcnew Microsoft::Office::Interop::Excel::ApplicationClass();
ExcelApp->Workbooks->Add(Type::Missing);
for (int i = 1; i < datagridview1->Columns->Count + 1;i++)
{
ExcelApp->Cells[1, i] = datagridview1->Columns[i - 1]->HeaderText;
}
for (int i = 0; i < datagridview1->Rows->Count; i++)
{
for (int j = 0; j < datagridview1->Columns->Count; j++)
{
ExcelApp->Cells[i+2,j+1] = datagridview1->Rows[i]->Cells[j]->Value->ToString();
}
}
ExcelApp->ActiveWorkbook->SaveCopyAs(saveFileDialog1->FileName->ToString());
ExcelApp->ActiveWorkbook->Saved=true;
ExcelApp->Quit();
I had a similar problem once, the problem is in rows and cells writhing your datagridview1 into file. Code should look like this:
saveFileDialog1->Title = "Save as Excel File";
saveFileDialog1->FileName = "";
saveFileDialog1->Filter = "Excel Files(2003)|*.xls|Excel Files(2007)|*.xlsx";
if(saveFileDialog1>ShowDialog()==System::Windows::Forms::DialogResult::OK){
Microsoft::Office::Interop::Excel::Application^ ExcelApp = gcnew Microsoft::Office::Interop::Excel::ApplicationClass();
ExcelApp->Workbooks->Add(Type::Missing);
for (int i = 1; i < datagridview1->Columns->Count + 1;i++)
{
ExcelApp->Cells[1, i] = datagridview1->Columns[i - 1]->HeaderText;
}
for (int i = 0; i < datagridview1->Rows->Count; i++)
{
for (int j = 0; j < datagridview1->Columns->Count; j++)
{
ExcelApp->Cells[i + 2, j + 1] = datagridview1->Rows[i]->Cells[j]->Value;
safe_cast<Range^>(ExcelApp->Cells[i + 2, j + 1]); }
}
ExcelApp->ActiveWorkbook->SaveCopyAs(saveFileDialog1->FileName->ToString());
ExcelApp->ActiveWorkbook->Saved=true;
ExcelApp->Quit();