copy a list to a SpreadSheetGear Irange - list

I have the following code:
using (CPASEntities ctx = new CPASEntities())
{
IWorksheet ws = wb.Worksheets[0];
ws.Name = "Summary";
var tsm = (from x in ctx.tblTimesheetMasters
where x.TSID == TSID
select new
{
TimesheetID = x.TSID,
Comments = x.TSComments,
Vendor = x.tblVendor.Vendor_Name,
StartDate = x.TSStartDate,
Author = x.TSAuthor,
Approver = x.TSApprover,
Override_Approver = x.TSOverrideApprover,
Status = x.tblTimesheetStatu.TSStatusDesc
}
).ToList();
SpreadsheetGear.IRange range = ws.Cells["A1"];
// I want to copy the entire tsm list to this range, including headings.
}
As the comment states, I want to put that entire list into the ws worksheet starting at A1. I include the code in case it's easier to use a different construct. FWIW, there will be only one entry...TSID is the primary key. I can, of course, use the .FirstorDefault() construct if that is important. I thought it not important.

Your range is only one cell. You need a range big enough to contain all the cells the list would populate.
To populate your worksheet with the list, you could do something like this.
int iRow = 0;
int iCol = 0;
if (tsm.Count() > 0)
{
foreach (var prop in tsm[0].GetType().GetProperties())
{
ws.Cells[iRow, iCol].Value = prop.Name;
iCol++;
}
iRow++;
foreach (var t in tsm)
{
iCol = 0;
foreach (var prop in t.GetType().GetProperties())
{
ws.Cells[iRow, iCol].Value = prop.GetValue(t, null);
iCol++;
}
iRow++;
}
}
If you want a range, you could add this line.
SpreadsheetGear.IRange range = ws.Cells[0, 0, iRow - 1, iCol - 1];

Related

Best way to refactor If-statement

I have the following code:
if (adSetting.Core_standard_application_role)
{
rc = new IntegrationRoleCompany();
rc.RoleCompany = firmSettings.FirmNo.ToString();
rc.RoleName = "Core standard application role";
rcList.Add(rc);
}
if (adSetting.Expense_Invoice_Application_Access)
{
rc = new IntegrationRoleCompany();
rc.RoleCompany = firmSettings.FirmNo.ToString();
rc.RoleName = "Expense Invoice Application Access";
rcList.Add(rc);
}
The problem is that I have 20 if-checks where I check addSetting.Property. Now to the question:
What is the best and most effective way to refactor this if-statements?
you could have a 20x2 array with the adSetting.STUFF_AS_STRING -> rc.RoleName mapping.
then loop over the array in a for loop
pseudo code:
for (var i=0; i<theArray.length; i++) {
adSettingStr, RoleName = theArray[i]
if (adSetting[adSettingStr]) {
rc = new IntegrationRoleCompany();
rc.RoleCompany = firmSettings.FirmNo.ToString();
rc.RoleName = RoleName;
rcList.Add(rc);
}
}

Search usernames with Regular Expressions

At the moment I'm trying to use a regular expression to find usernames. The following condition is what I need:
"Username matches the search term with a maximum of 3 wrong characters"
For example,
Database content:
"MyUsername"
Search command -> returning match:
search("Username") -> "MyUsername"
search("Us3rname") -> "MyUsername"
search("userName") -> "MyUsername"
search("MyUser") -> none (4 characters wrong)
search("My Us3r N#me") -> none (4 characters wrong)
I can build my regex dynamically and push this to a database query. I only can't get a grip on the regex itself. Could you help me with this? Would be great? (or is it even possible?)
You can't do this with regular expression. You need some similarity algorithm to check the similarity between two strings.
A good start and an easy one is the levensthein distance.
In short: It calculates how many Insert/Update/Delete Operations are needed to transform string A to string B.
I had done this in Javascript some years ago, but it should be easy in nearly every programming language. You can find a working example here:
// http://ejohn.org/blog/fast-javascript-maxmin/
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Array.min = function( array ){
return Math.min.apply( Math, array );
};
// Levenshstein Distance Calculation
function levenshtein_distance (t1, t2) {
var countI = t1.length+1;
var countJ = t2.length+1;
// build empty 'matrix'
var matrix = new Array (countI);
for (var i=0;i<countI;i++) {
matrix[i] = new Array (countJ);
}
// initialize the matrix;
// set m(0,0) = 0;
// m(0,0<=j<countJ) = j
// m(0<=i<countI, 0) = i
matrix[0][0] = 0;
for (var j=1;j<matrix[0].length;j++) {
matrix[0][j] = j;
}
for (var i=1;i<matrix.length;i++) {
matrix[i][0] = i;
}
// calculate the matrix
for (var i=1;i<matrix.length;i++) {
for (var j=1;j<matrix[i].length;j++) {
var costs = new Array ();
if (t1.charAt(i-1) == t2.charAt(j-1)) {
costs.push (matrix[i-1][j-1]);
}
costs.push (matrix[i-1][j-1] + 1);
costs.push (matrix[i][j-1] + 1);
costs.push (matrix[i-1][j] + 1);
matrix[i][j] = Array.min(costs);
}
}
// resultMatrix = matrix;
var result = new Object
result.distance = matrix[countI-1][countJ-1];
result.matrix = matrix;
return result;
}

Adding items to a Google Forms list from a spreadsheet range

I am struggling to get past the last line in this code any help will be appreciated:
The error I am getting is "Array is empty: values (line 16, file "Code")". I have double checked the item ID, the spreadsheet ID and that there is data for it to pick up within the correct range. Any pointers or insights...?
function GetFleet() {
var ssDEFECTS = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var rngFLEET = ssDEFECTS.getDataRange();
var values = rngFLEET.getValues();
var FleetList = [];
//Use column 0 and ignore row 1 (headers)
for (var i = 1; i <= values.length; i++) {
var v = values[i] && values[i][0];
v && values.push(v)
}
// Form ID & List ID
var DefectsForm = FormApp.openById('<FORM KEY ID>');
DefectsForm.getItemById(794194842).asListItem().setChoiceValues(FleetList);
};
Nothing is pushed to your array FleetList. Also the coding in your loop is faulty.
Assuming you want to push the first column (not including the header),
try this and see if it works
function GetFleet() {
var values = SpreadsheetApp.getActiveSpreadsheet()
.getSheets()[0].getDataRange()
.getValues();
var FleetList = [];
//Use column 0 and ignore row 1 (headers)
for (var i = 1, len = values.length; i < len; i++) {
FleetList.push(values[i][0])
}
// Form ID & List ID
var DefectsForm = FormApp.openById('<FORM KEY ID>');
DefectsForm.getItemById(794194842)
.asListItem()
.setChoiceValues(FleetList);
};

CouchDB list view error when no key requested

Having trouble with a list function I wrote using CouchApp to take items from a view that are name, followed by a hash list of id and a value to create a CSV file for the user.
function(head, req) {
// set headers
start({ "headers": { "Content-Type": "text/csv" }});
// set arrays
var snps = {};
var test = {};
var inds = [];
// get data to associative array
while(row = getRow()) {
for (var i in row.value) {
// add individual to list
if (!test[i]) {
test[i] = 1;
inds.push(i);
}
// add to snps hash
if (snps[row.key]) {
if (snps[row.key][i]) {
// multiple call
} else {
snps[row.key][i] = row.value[i];
}
} else {
snps[row.key] = {};
snps[row.key][i] = row.value[i];
}
//send(row.key+" => "+i+" => "+snps[row.key][i]+'\n');
}
}
// if there are individuals to write
if (inds.length > 0) {
// sort keys in array
inds.sort();
// print header if first
var header = "variant,"+inds.join(",")+"\n";
send(header);
// for each SNP requested
for (var j in snps) {
// build row
var row = j;
for (var k in inds) {
// if snp[rs_num][individual] is set, add to row string
// else add ?
if (snps[j][inds[k]]) {
row = row+","+snps[j][inds[k]];
} else {
row = row+",?";
}
}
// send row
send(row+'\n');
}
} else {
send('No results found.');
}
}
If I request _list/mylist/myview (where mylist is the list function above and the view returns as described above) with ?key="something" or ?keys=["something", "another] then it works, but remove the query string and I get the error below:
{"code":500,"error":"render_error","reason":"function raised error: (new SyntaxError(\"JSON.parse\", \"/usr/local/share/couchdb/server/main.js\", 865)) \nstacktrace: getRow()#/usr/local/share/couchdb/server/main.js:865\n([object Object],[object Object])#:14\nrunList(function (head, req) {var snps = {};var test = {};var inds = [];while ((row = getRow())) {for (var i in row.value) {if (!test[i]) {test[i] = 1;inds.push(i);}if (snps[row.key]) {if (snps[row.key][i]) {} else {snps[row.key][i] = row.value[i];}} else {snps[row.key] = {};snps[row.key][i] = row.value[i];}}}if (inds.length > 0) {inds.sort();var header = \"variant,\" + inds.join(\",\") + \"\\n\";send(header);for (var j in snps) {var row = j;for (var k in inds) {if (snps[j][inds[k]]) {row = row + \",\" + snps[j][inds[k]];} else {row = row + \",?\";}}send(row + \"\\n\");}} else {send(\"No results found.\");}},[object Object],[object Array])#/usr/local/share/couchdb/server/main.js:979\n(function (head, req) {var snps = {};var test = {};var inds = [];while ((row = getRow())) {for (var i in row.value) {if (!test[i]) {test[i] = 1;inds.push(i);}if (snps[row.key]) {if (snps[row.key][i]) {} else {snps[row.key][i] = row.value[i];}} else {snps[row.key] = {};snps[row.key][i] = row.value[i];}}}if (inds.length > 0) {inds.sort();var header = \"variant,\" + inds.join(\",\") + \"\\n\";send(header);for (var j in snps) {var row = j;for (var k in inds) {if (snps[j][inds[k]]) {row = row + \",\" + snps[j][inds[k]];} else {row = row + \",?\";}}send(row + \"\\n\");}} else {send(\"No results found.\");}},[object Object],[object Array])#/usr/local/share/couchdb/server/main.js:1024\n(\"_design/kbio\",[object Array],[object Array])#/usr/local/share/couchdb/server/main.js:1492\n()#/usr/local/share/couchdb/server/main.js:1535\n#/usr/local/share/couchdb/server/main.js:1546\n"}
Can't say for sure since you gave little detail, however, a probable source of problems, is the use of arrays to collect data from every row: it consumes an unpredictable amount of memory. This may explain why it works when you query for a few records, and fails when you query for all records.
You should try to arrange data in a way that eliminates the need to collect all values before sending output to the client. And keep in mind that while map and reduce results are saved on disk, list functions are executed on every single query. If you don't keep list function fast and lean, you'll have problems.

Open XML Excel Cell Formatting

I am trying to export to excel using Open XML with simple formatting. Export to Excel is working. The problem is with formatting the data. I am trying to have very basic formatting. i.e. the Column names should be in bold and rest of the content in normal font. This is what I did. Please let me know where am I going wrong.
private Stylesheet GenerateStyleSheet()
{
return new Stylesheet(
new Fonts(
new Font(new DocumentFormat.OpenXml.Spreadsheet.FontSize { Val = 12},
new Bold(),
new Font(new DocumentFormat.OpenXml.Spreadsheet.FontSize { Val = 12}))
)
);
}
protected void ExportExcel(DataTable dtExport)
{
Response.ClearHeaders();
Response.ClearContent();
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
//"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" '"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" '"application/vnd.ms-excel"
Response.AddHeader("content-disposition", "attachment; filename=Test.xlsx");
Response.Charset = "";
this.EnableViewState = false;
MemoryStream ms = new MemoryStream();
SpreadsheetDocument objSpreadsheet = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook);
WorkbookPart objWorkbookPart = objSpreadsheet.AddWorkbookPart();
objWorkbookPart.Workbook = new Workbook();
WorksheetPart objSheetPart = objWorkbookPart.AddNewPart<WorksheetPart>();
objSheetPart.Worksheet = new Worksheet(new SheetData());
Sheets objSheets = objSpreadsheet.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet objSheet = new Sheet();
objSheet.Id = objSpreadsheet.WorkbookPart.GetIdOfPart(objSheetPart);
objSheet.SheetId = 1;
objSheet.Name = "mySheet";
objSheets.Append(objSheet);
WorkbookStylesPart stylesPart = objSpreadsheet.WorkbookPart.AddNewPart<WorkbookStylesPart>();
stylesPart.Stylesheet = GenerateStyleSheet();
stylesPart.Stylesheet.Save();
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
for (int cols = 0; cols < dtExport.Columns.Count; cols++)
{
Cell objCell = InsertCellInWorksheet(GetColumnName(cols), 1, objSheetPart);
objCell.CellValue = new CellValue(dtExport.Columns[cols].ColumnName);
objCell.DataType = new EnumValue<CellValues>(CellValues.String);
objCell.StyleIndex = 0;
}
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
for (uint row = 0; row < dtExport.Rows.Count; row++)
{
for (int cols = 0; cols < dtExport.Columns.Count; cols++)
{
//row + 2 as we need to start adding data from second row. First row is left for header
Cell objCell = InsertCellInWorksheet(GetColumnName(cols), row + 2, objSheetPart);
objCell.CellValue = new CellValue(Convert.ToString(dtExport.Rows[Convert.ToInt32(row)][cols]));
objCell.DataType = new EnumValue<CellValues>(CellValues.String);
objCell.StyleIndex = 1;
}
}
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
objSpreadsheet.Close();
ms.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
// Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet.
// If the cell already exists, return it.
private Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart)
{
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
string cellReference = (columnName + rowIndex.ToString());
// If the worksheet does not contain a row with the specified row index, insert one.
Row row = default(Row);
if ((sheetData.Elements<Row>().Where(r => r.RowIndex.Value == rowIndex).Count() != 0))
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex.Value == rowIndex).First();
}
else
{
row = new Row();
row.RowIndex = rowIndex;
sheetData.Append(row);
}
// If there is not a cell with the specified column name, insert one.
if ((row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex.ToString()).Count() > 0))
{
return row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).First();
}
else
{
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
Cell refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if ((string.Compare(cell.CellReference.Value, cellReference, true) > 0))
{
refCell = cell;
break; // TODO: might not be correct. Was : Exit For
}
}
Cell newCell = new Cell();
newCell.CellReference = cellReference;
row.InsertBefore(newCell, refCell);
return newCell;
}
}
It seems like you are missing a ")" after your first font creation. So then you end opp with only one font index (the default one)
Below is the code I use for exactly what you are asking for.
You might remove fills and borders and remove them from cellformat, but I had some syntax problems while writing this so I just left it when it all worked :-)
private Stylesheet GenerateStyleSheet()
{
return new Stylesheet(
new Fonts(
// Index 0 - Default font.
new Font(
new FontSize() { Val = 11 },
new Color() { Rgb = new HexBinaryValue() { Value = "000000" } }
),
new Font(
new Bold(),
new FontSize() { Val = 11 },
new Color() { Rgb = new HexBinaryValue() { Value = "000000" } }
)
),
new Fills(
// Index 0 - Default fill.
new Fill(
new PatternFill() { PatternType = PatternValues.None })
),
new Borders(
// Index 0 - Default border.
new Border(
new LeftBorder(),
new RightBorder(),
new TopBorder(),
new BottomBorder(),
new DiagonalBorder())
),
new CellFormats(
// Index 0 - Default cell style
new CellFormat() { FontId = 0, FillId = 0, BorderId = 0 },
new CellFormat() { FontId = 1, FillId = 0, BorderId = 0, ApplyFont = true }
)
);
}