I have to do a Excel Manager with C# and i choose to use Gem Box Spreadsheet Free
var ef = new ExcelFile();
ef = ExcelFile.Load(File_Lettura);
ExcelWorksheet ws = ef.Worksheets.ActiveWorksheet;
int riga = 13;
string s = (ws.Cells["B6"]).ToString();
string[] r = s.Split('-');
int c = 0;
while (ws.Cells["B"+riga.ToString()].Value != null)
{
if (ws.Cells["F"+riga.ToString()].Value.ToString() != "")
{
// add row
dgwFile.Rows.Add();
dgwFile.Rows[c].Cells[0].Value = r[0] + "-" + r[1] + "-" + ws.Cells["B"+riga.ToString()].Value.ToString();
dgwFile.Rows[c].Cells[1].Value = ws.Cells["D" + riga.ToString()].Value.ToString() + ws.Cells["G" + riga.ToString()].Value.ToString() + ws.Cells["H" + riga.ToString()].Value.ToString() + ws.Cells["I" + riga.ToString()].Value.ToString();
dgwFile.Rows[c].Cells[2].Value = ws.Cells["F" + riga.ToString()].Value.ToString();
dgwFile.Rows[c].Cells[3].Value = "0";
c++;
}
riga++;
}
VS give me a problem at the first "IF" with error :
An unhandled exception of type 'System.NullReferenceException'
occurred.
I think the wrong rows are the first 3
thanks in advance Smile | :)
i've also tried like it
ExcelFile ef = ExcelFile.Load(File_Lettura);
ExcelWorksheet ws = ef.Worksheets.ActiveWorksheet;
I don't believe the first 3 lines are the problem, however in order to be 100% sure you would need to specify exactly where the exception is thrown.
Nevertheless I presume one of the ExcelCell's that you are targeting is null.
So try this:
while (ws.Cells["B"+riga.ToString()] != null &&
ws.Cells["B"+riga.ToString()].Value != null)
{
if (ws.Cells["F"+riga.ToString()] != null &&
ws.Cells["F"+riga.ToString()].Value != null)
{
Related
I am generating excel with EPPlus and it was opening but the moment i applied condition formatting excel generation slow and file is opening in my pc but not opening in another pc.
For conditional formatting right font color is coming. my objective of conditional formatting is if cell value >-1 then color will be Green and if cell value is <0 then color will be red. The code i got from google search for conditional formatting which is working fine when i open excel file in my pc but when same excel open in another pc there a error is coming for conditional formatting.
Here i am sharing my conditional formatting code. please have a look and tell me does it applied properly or code is not right one.
#region Conditional Formatting
address = new ExcelAddress(AvgPeriod3 + row.ToString());
_statement1 = "=AND($" + address + ">-1)";
condition = ws.ConditionalFormatting.AddExpression(address);
condition.Formula = _statement1;
condition.Style.Font.Color.Color = System.Drawing.Color.Green;
address = new ExcelAddress(AvgPeriod3 + row.ToString());
_statement1 = "=AND($" + address + "<0)";
condition = ws.ConditionalFormatting.AddExpression(address);
condition.Formula = _statement1;
condition.Style.Font.Color.Color = System.Drawing.Color.Red;
#endregion
if the above code is not right one for my requirement then please suggest me what to change in the above code.
another things not clear that excel file is opening in my pc but throwing error regarding conditional formatting when try to open in another pc. excel version is more less same or close in two pc.
Thanks
This way you can add conditional formatting.
string _StartPeriod = "", _EndPeriod = "";
//_EarningID_Periods
for (int p = 0; p <= _EarningID_Periods.Count - 1; p++)
{
Period = _EarningID_Periods[p].NewPeriod.Replace("A", "").Replace("E", ""); //ds.Tables[1].Rows[p]["old_Periods"].ToString().Replace("A", "").Replace("E", "");
_StartPeriod = listOfCell.Where(a => a.EarningsType == "NEW"
&& a.PeriodType == "DELTA_PERCENTAGE_PERIOD" && a.Period.Replace("A", "").Replace("E", "") == Period
).FirstOrDefault().CoorDinate + "4";
_EndPeriod = listOfCell.Where(a => a.EarningsType == "NEW"
&& a.PeriodType == "DELTA_ABSOLUTE" && a.Period.Replace("A", "").Replace("E", "") == Period
).FirstOrDefault().CoorDinate + row.ToString();
if (_StartPeriod != "" && _EndPeriod != "")
{
ExcelAddress formatRangeAddress = new ExcelAddress(_StartPeriod + ":" + _EndPeriod);
var cond1 = ws.ConditionalFormatting.AddLessThan(formatRangeAddress);
cond1.Style.Font.Color.Color = CSMUtils._RedColor;
cond1.Formula = "0";
formatRangeAddress = new ExcelAddress(_StartPeriod + ":" + _EndPeriod);
var cond2 = ws.ConditionalFormatting.AddGreaterThan(formatRangeAddress);
cond2.Style.Font.Color.Color = CSMUtils._GreenColor; //CSMUtils.SetRGBColor(0, 97, 0);
cond2.Formula = "0";
}
}
I have tried to wipe this data while trying to export a database into my program.
The basic problem is that I do not know why he can not use LIKE in my SQL statement.
So I wanted to catch all DataRows and write them into an array, which I can edit later.
The program throws an exception:
Error message: System.IndexOutOfRangeException: "The index was outside the array area."
If I did something unusual or wrong in my Post I sincerely apologies, this is my first entry in this forum.
Code:
public void TestQuery()
{
string file = #"C:\Users\Michael\Downloads\7z1900-x64.msi";
// Get the type of the Windows Installer object
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
// Create the Windows Installer object
WindowsInstaller.Installer installer = (WindowsInstaller.Installer)Activator.CreateInstance(installerType);
// Open the MSI database in the input file
Database database = installer.OpenDatabase(file, 0);
// Open a view on the Property table for the version property
View view = database.OpenView("SELECT * FROM `File`");
// Execute the view query
view.Execute(null);
// Get the record from the view
Record record = view.Fetch();
int i = 1;
string[] sreturns = new string[60];
while (record != null)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
sreturns[i] = record.get_StringData(0).ToString();
i++;
}
}
First thing I see is that you're starting at 1, while (C#) arrays are 0-based.
In you screenshot I see that i is 60, so that would be the problem. Index 60 doesn't actually exist in your array, as it goes from 0 to 59.
You can add i < sreturns.Length to make sure you are in the array range.
Also, make sure you start with i = 0 and not 1.
int i = 0;
string[] sreturns = new string[60];
while (record != null && i < sreturns.Length)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
sreturns[i] = record.get_StringData(0).ToString();
i++;
}
Why not using a list instead of an array?
List<string> sreturns = new List<string>();
while (record != null)
{
try
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
var result = record.get_StringData(0);
sreturns.Add(result.ToString());
}
catch (Exception e)
{
Console.WriteLine("No record...");
}
}
This way you dont need to worry about the array size - its maintainable -efficient - and if in the future the size change you don't have to worry about it.
List documentation here
What is the query with LIKE that you have tried? The following should work:
SELECT * FROM File WHERE FileName LIKE '%.exe' OR FileName LIKE '%.msi'
EDIT: On further investigation (https://learn.microsoft.com/en-us/windows/win32/msi/sql-syntax), the documentation seems to imply that the LIKE operator is not supported. But you could start off with an IS NOT NULL and do more complex filtering in the loop, like you're doing.
EDIT 2, expanding on Alex Leo's answer.
List<string> sreturns = new List<string>();
while (record != null)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
var result = record.get_StringData(0);
if(!string.IsNullOrWhiteSpace(result) && (result.EndsWith(".exe") || result.EndsWith(".msi")))
{
sreturns.Add(result.ToString());
}
record = view.Fetch();
}
Note that the view.Fetch() inside the while loop has been moved to the end, or you would skip the first record, as well as get another null reference when the last record has already been read, but the while loop executes one more time.
public void MatchedDocumentsInFileCabinet(string MainFolder, string SubFolder, string FileName, string FilePath)
{
// Checking Main Folder is present in FileCabinet, if present retrieving MainFolderID if not Inserting MainFolderName
if (SelectedFileCabinetID == "")
{
SelectedFileCabinetID = "1";
}
int Mainfoldercount = 0;
DocSortResult getfolderdetails = objFolderManager.GetFolderDetails();
DataTable getFolderNames = new DataTable();
if (getfolderdetails.resultDS != null && getfolderdetails.resultDS.Tables[0].Rows.Count > 0)
{
// Following line is showing error
DataRow[] drResult = getfolderdetails.resultDS.Tables[0].Select("FileCabinet_ID = '" + SelectedFileCabinetID + "'" + "and" + " ParentFolderID = '" + "0" + "'" + "and" + " IsDelete = '" + "True" + "'");
if (drResult.Count() != 0)
{
getFolderNames = drResult.CopyToDataTable();
}
}
}
Without knowing getfolderdetails.resultDS.Tables[0] structure is hard to know which column is, but one of those columns is integer and your Select(filter) is telling that all the fields are string.
An example of your code debugging would show .Select("FileCabinet_ID = '4' and ParentFolderID = '0' and IsDelete = 'True' "). And the error message says one of them is not a string.
I would bet that IsDelete = 'True' probably will be boolean (bit column in SQL Server) and FileCabinet_ID or ParentFolderID or both of them are integer (and this is causing the error).
Set a breakpoint and check the datatypes of the datacolumns you are trying to filter.
I have a file with some rows and I can read everything, but I will get an error if one column has a empty cell.
What should I do?
while ((line = reader.ReadLine()) != null) {
FundPriceModel model = new FundPriceModel();
if (isColumn) {
model.Columns = line.Split(spliter[0]);
isColumn = false;
} else {
string[] row = line.Split(spliter);
model.LipperID = Int32.Parse(row[0]);
model.PriceDate = DateTime.Parse(row[1]);
model.PriceCode = row[2][0];
model.PriceType = row[3][0];
model.PriceCurrency = row[4];
model.PriceValueLC = float.Parse(row[5]);
model.Estimate = row[6][0];
Console.WriteLine(model.LipperID + "\t" + model.PriceDate + "\t" + model.PriceCode + "\t" + model.PriceType + "\t" + model.PriceCurrency + "\t" + model.PriceValueLC + "\t" + model.Estimate);
}
}
Table:
The error is probably when you try to parse something. This leads me to believe that you need to use TryParse instead or Parse :)
Something like this: int x; int? val=int.TryParse(row[0],out x)?x:(int?)null;
Also, row[3][0] gets the first letter in an existing string and returning an error when the string is empty. You could encapsulate it somewhat like this:
private T safeValue<T>(string text, Func<string,T> func) {
if (string.IsNullOrEmpty(text)) return default(T);
return func(text)
}
and you would use it like this:
model.LipperID = safeValue(row[0],v=>Int32.Parse(v));
model.PriceCode = safeValue(row[2], v=>v[0]);
I have a table that is dynamically created in some c# code-behind when a dropdown is changed. There 9 columns in this table. The first 8 should be in one group. The last attribute in another. When the last attribute is selected I want the first 8 to go unchecked. When any of the first 8 are checked I wanted the last attribute to go unchecked. I added some javascript and it works but it causes the tables to load extremely slow. If there is a simpler way please let me know. Thanks!
adding javascript function calls through c#
attr1.Attributes.Add("onClick", "uncheckOK(" + rowCount + ");");
attr2.Attributes.Add("onClick", "uncheckOK(" + rowCount + ");");
attr3.Attributes.Add("onClick", "uncheckOK(" + rowCount + ");");
attr4.Attributes.Add("onClick", "uncheckOK(" + rowCount + ");");
attr5.Attributes.Add("onClick", "uncheckOK(" + rowCount + ");");
attr6.Attributes.Add("onClick", "uncheckOK(" + rowCount + ");");
attr7.Attributes.Add("onClick", "uncheckOK(" + rowCount + ");");
attr8.Attributes.Add("onClick", "uncheckOK(" + rowCount + ");");
attr9.Attributes.Add("onClick", "uncheckAttr(" + rowCount + ");");
functions to uncheck
function uncheckAttr(row) {
var chk1 = document.getElementById("MainContent_attr1-" + row);
chk1.checked = false;
var chk2 = document.getElementById("MainContent_attr2-" + row);
chk2.checked = false;
var chk3 = document.getElementById("MainContent_attr3-" + row);
chk3.checked = false;
var chk4 = document.getElementById("MainContent_attr4-" + row);
chk4.checked = false;
var chk5 = document.getElementById("MainContent_attr5-" + row);
chk5.checked = false;
var chk6 = document.getElementById("MainContent_attr6-" + row);
chk6.checked = false;
var chk7 = document.getElementById("MainContent_attr7-" + row);
chk7.checked = false;
var chk8 = document.getElementById("MainContent_attr8-" + row);
chk8.checked = false;
}
function uncheckOK(row) {
var chk9 = document.getElementById("MainContent_attr9-" + row);
chk9.checked = false;
}
Can't you just do this via standard HTML? Make a set of radio buttons - give columns 1-8 the same name attribute, and give the 9th one a different name. You should only be able to select one or the other.
Alternatively, strip out that ugly code and use some jQuery. Something like:
$('table.your-table input[type=radio]').click(function(){
$('table.your-table input[type=radio]').not(this).removeAttr('checked');
});
EDIT: Actually the HTML option won't work, but I encourage you to do this via jQuery, it's what it's built for.
function uncheck() {
var clickSource = event.srcElement;
if (clickSource != null) {
var fullid = clickSource.name;
if (fullid != null) {
if (fullid.indexOf('attr') != -1) {
var checkboxid = fullid.substring(fullid.indexOf('attr'));
var row = checkboxid.substring(checkboxid.indexOf('-') + 1);
var attr = checkboxid.substring(checkboxid.indexOf('-') - 1, checkboxid.indexOf('-'));
if (attr == '9') {
uncheckAttr(row);
}
else {
uncheckOK(row);
}
}
}
}
}