c# cannot read special character from a text file - c#

In the text file, I create a list for user input their condition, in order to filter out these four value in the excel file.
abc=<>10,<>20,<>30,<>40
And into program, I wrote this to read the list:
try
{
abc = dic["abc"];
if (abc == null || abc.Trim() == "")
{
MessageBox.Show("abc can't be empty!");
this.Close();
}
}
catch (KeyNotFoundException)
{
MessageBox.Show("abc can't be found in Config.txt!");
this.Close();
}
And in the final steps, I want to add the list into string list in my source code, then use autofilter function to filter the excel
string[] abc_list = abc.Split(',');
newSheet.Range["$A:$OO"].AutoFilter(12, abc_list, Excel.XlAutoFilterOperator.xlFilterValues);
And this is the error I got:
23:49:16
Line No.: 5778
System.Runtime.InteropServices.COMException (0x800A03EC): _AutoFilter method of Range class failed
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at Microsoft.Office.Interop.Excel.Range.AutoFilter(Object Field, Object Criteria1, XlAutoFilterOperator Operator, Object Criteria2, Object VisibleDropDown)
But I found that it is not working. Can anyone tell me why?
Thanks.

I found that change .xlFilterValue to .xlOr can solve this question.

Related

Read Text File, Update Fields C# and WPF

I am trying to basically create config files. A text file will hold something like:
Name::Adam
Location::Washington
I am trying to grab the first part as the field name (i.e. Name.Text would update the TextBox) then put the second part to that Text. Just not sure where to go or what the best way to build this is. The code below is incomplete because I can't figure out how to update the textboxes.
Thanks for the help!
private void clickImportConfig_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
{
Stream myStream = null;
string fieldUpdate = string.Empty;
string fieldUpdateTo = string.Empty;
try
{
using (myStream)
{
string[] lines = File.ReadAllLines(#"c:\\config.txt");
foreach (string s in lines)
{
var splitted = Regex.Split(s, "::");
fieldUpdate = splitted[0].ToString();
fieldUpdateTo = splitted[1].ToString();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
I think this is what you're looking for:
private void clickImportConfig_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
{
Stream myStream = null;
string fieldUpdate = string.Empty;
string fieldUpdateTo = string.Empty;
try
{
using (myStream)
{
string[] lines = File.ReadAllLines(#"c:\\config.txt");
foreach (string s in lines)
{
string[] splitted = s.Split(new string[] { "::" }, StringSplitOptions.RemoveEmptyEntries);
fieldUpdate = splitted[0].ToString();
fieldUpdateTo = splitted[1].ToString();
// TextBox textBox = (TextBox)this.FindName(fieldUpdate);
// Or
TextBox textBox = this.FindName(fieldUpdate) as TextBox;
// See below for an explanation
if (textBox != null) // FindName returns null if nothing is found with that name
{
textBox.Text = fieldUpdateTo;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
As insane_developer pointed out, you will be better off using the String.Split method (s being the string in this case so written as s.Split()) instead of Regex.Split. It will give you the benefit of removing any empty results from the array. It may also have better performance as Regex is capable of a lot more complicated things, but I haven't tested that so I could be wrong.
You can use the FindName(string name) method to find an element with the specified name. This method returns null if nothing is found and an object if the element is found. This object will need to be cast to the type you are expecting (I.e. TextBox). You can do this in one of the following ways:
TextBox textBox = (TextBox)this.FindName(fieldUpdate);
or
TextBox textBox = this.FindName(fieldUpdate) as TextBox;
The first option will throw an InvalidCastException if FindName returns an object which is not a TextBox. The second option will instead just set the value of textBox to null which will be checked by the if statement and the exception will be avoided. As you are only catching all generic exceptions in this code, an InvalidCastException would show your "Could not read file from disk" message which is not true. So you may want to add an additional catch block to handle any invalid casting.
If you're wondering why you don't just stick to the second option as it solves this problem, then consider this scenario as an example. Lets say in the future you decide for some reason that you want to change all of your TextBox to TextBlock or something else, but forget to come back to change this code, or accidently end up with the name of another type of control in your text file. The second option will set the value of textBox to null and your field(s) won't be updated. But there will be absolutely no errors, leaving you scratching your head and having to debug the problem. The first option would throw an InvalidCastException showing you exactly where the problem is. You could then choose how to handle this problem by either showing another message box or silently writing the error to a log file etc.
You don't need a regular expression, just:
var splitted = s.Split("::", StringSplitOptions.RemoveEmptyEntries);
fieldUpdate = splitted[0];
fieldUpdateTo = splitted[1];
For the rest you have to be more explicit

Specified cast is not valid by sharepoint.linq.dll

I am writing code to check if an item exist in a sharepoint document library, I have generated entity classes using sp metal. The code is below:
public bool? checkRSA(string pin)
{
bool ?checkIfRsaExists = null;
SPSecurity.RunWithElevatedPrivileges(delegate ()
{
string siteURL = "http://dms.site.com/sites/DirOperations/CustomerCare";
CustomercareDataContext CustCareDB = new CustomercareDataContext(siteURL);
checkIfRsaExists = CustCareDB.GetList<BenefitsCT>("RSAs Library").ScopeToFolder("", true).Any(x => x.RSAPIN == pin);
});
return checkIfRsaExists;
}
Now each time I run this code it throws an error: Specified cast is not valid.
The stack trace is below:
StackTrace at Set__permi(Object , Object )\r\n at
Microsoft.SharePoint.Linq.SPItemMappingInfo.MaterializeEntity[TEntity](DataContext
dc, SPDataList list, SPListItem item, SPItemMappingInfo
itemMappingInfo, JoinPath joinPath)\r\n at lambda_method(Closure ,
SPListItem )\r\n at
System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()\r\n
at System.Linq.Enumerable.Any[TSource](IEnumerable1 source, Func`2
predicate)\r\n at
Microsoft.SharePoint.Linq.SPLinqProvider.Execute[T](Expression
expression)\r\n at
linkApprovals.WebService1.<>c__DisplayClass2_0.b__0() in
c:\users\sp_admin\documents\visual studio
2015\Projects\linkApprovals\linkApprovals\WebService1.asmx.cs:line
75\r\n at
Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated
secureCode)" string
I was able to figure this out. It turns out the context file generated by SP Metal is corrupt. The stack trace pointed out the solution. I removed the __permi(Object , Object ) and it worked perfectly.

Range Validator in Excel with custom message text

I have the following code to give a Excel cell Validation with custom text.
var cellValues = activeSheet.Range[columnLetterValue + startingRow, Type.Missing];
cellValues.Validation.Add(XlDVType.xlValidateCustom, XlDVAlertStyle.xlValidAlertInformation, XlFormatConditionOperator.xlBetween, cellValues.Value2, Type.Missing);
cellValues.Validation.IgnoreBlank = true;
cellValues.Validation.ErrorTitle = "Custom error title";
cellValues.Validation.ErrorMessage = "Custom error message description";
cellValues.Validation.ShowError = true;
cellValues.Validation.ShowInput = false;
When debugging the line to set the ErrorTitle or ErrorMessage a 'System.Runtime.InteropServices.COMException' is thrown.
Stacktrace:
{System.Runtime.InteropServices.COMException (0x800A03EC): Exception
from HRESULT: 0x800A03EC at
System.RuntimeType.ForwardCallToInvokeMember(String memberName,
BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData&
msgData) at
Microsoft.Office.Interop.Excel.Validation.set_ErrorTitle(String )
I have looked online and found a couple of examples that show this is possible:
Range Validation with Excel using C#
I've even recorded a Macro in Excel and it works with the "VBA" equivilent code:
ActiveCell.FormulaR1C1 = "Custom"
Range("A1").Select
With Selection.Validation
.Delete
.Add Type:=xlValidateCustom, AlertStyle:=xlValidAlertInformation, _
Operator:=xlBetween, Formula1:="Custom"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = "UDF Title"
.InputMessage = ""
.ErrorMessage = "The message"
.ShowInput = False
.ShowError = True
End With
End Sub
I've also tried different combinations of XlDVType and XlFormatConditionOperator but that didn't seem to make any difference in setting the custom messagebox text.
Does anyone know how to set a Validation rule with custom ErrorTitle and ErrorMessage?
The problem was due to setting a Validation.ErrorTitle to a range that didn't have a Validation rule.

Why would Type.GetType return null with telerik types in sitefinity?

I have set up a widget for the backend of my Sitefinity site that has three textboxes and a button. The goal is to create a new column in the database:
protected void btnAddClick(object sender, EventArgs e)
{
Type TelerikType = Type.GetType(txtTelType.Text);
Type ColumnType = Type.GetType(txtColType.Text);
string error = "";
if (TelerikType == null)
{
error = "Telerik Type is invalid";
}
if (ColumnType == null)
{
error = "Column Type is invalid";
}
if (error.Length == 0)
{
App.WorkWith()
.DynamicData()
.Type(TelerikType)
.Field()
.TryCreateNew(txtName.Text, ColumnType)
.SaveChanges(true);
error = "Added column successfully";
txtColType.Text = txtName.Text = txtTelType.Text = "";
}
literalErrorText.Text = string.Format(literalErrorText.Text, error);
}
I am having two problems:
When I enter Telerik.Sitefinity.Pages.Model.PageNode into the textbox, Type.GetType(txtTelType.Text) is returning null.
If I replace that portion with typeof(PageNode) I get "Specified type 'Telerik.Sitefinity.Pages.Model.PageNode' is not a dynamic type."
I'm hoping somebody might have some insight as to why these things wouldn't work correctly, or possibly a better way to approach this issue? For reference, my goal (at least for now) is to add a dynamic column that references PageNode so that I can specify a ShowInLeftNavigation boolean and a ShowInRightNavigation boolean. Thank you for any help you can provide.
Read the docs carefully here:
typeName Type: System.String
The assembly-qualified name of the type
to get. See AssemblyQualifiedName. If the type is in the currently
executing assembly or in Mscorlib.dll, it is sufficient to supply the
type name qualified by its namespace.
So if the type is not one of the base .Net types, or in the currently executing assembly, you have to tell GetType what assembly to look in as well.
I don't know what assembly the Telerik control are in, but it looks like you will have to add the assembly to the type name, something linke this:
TopNamespace.SubNameSpace.ContainingClass, MyAssembly,
Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089
Follow the link for "AssemblyQualifiedName" above to get all the gory details of the syntax.
Type.GetType doesn't that check for Object type
for example System.String ect... can you try replacing the = null with
if (TelerikType.Equals(null))

C# Cut/Copy & Paste objects

This is a 2 parter.
First I am having a heck of a time getting the paste part of a copy and paste operation to work.
I have a method that copies information to the Clipboard, works perfectly.
private void CopyData(string format, object data, string text)
{
bool addedData = false;
DataObject copyData = new DataObject();
if (!string.IsNullOrEmpty(text))
{
copyData.SetData(DataFormats.Text, text);
addedData = true;
}
if (!string.IsNullOrEmpty(format) && data != null)
{
copyData.SetData(format, false, data);
addedData = true;
//this is only for testing
object obj = null;
if (copyData.GetDataPresent(format))
obj = (object)copyData.GetData(format);
}
if (addedData)
Clipboard.SetDataObject(copyData, true);
}
When I check that the data was added the object (obj) is not null.
However when I then go to paste the data from a different method using the same format key I get null, every time.
private void PasteFromClipboard()
{
object obj = null;
IDataObject paste = null;
if (Clipboard.GetDataObject().GetDataPresent("mydatatype"))
obj = (object)Clipboard.GetDataObject().GetData("mydatatype");
else
return;
if (obj == null)
throw new NullReferenceException("Could not gather information from the
}
I have tried everything that I can think of and it just doesn't make sense. I created an array of strings to capture all of the format keys the DataObject was holding and "mydatatype" was the first one. I have tried casting, not casting, using (Clipboard.GetDataObject().GetData("mydatatype") as object) and I just cannot figure it out. I know that there is data there because I can go to NotePad and paste the text that I copied along with the object.
Any thoughts as to why I would be able to get the data in one method, but not another?
Secondly I was wondering how I would go about making a Cut & Paste operation work between two of my windows. I am thinking about something like Excel, where if only the text is pasted the data will remain, however if the objects are pasted then the source will be deleted.
Thanks
Patrick.
Try pulling the data out as Text (instead of "mydatatype") - at least to confirm you can read from the clipboard. This is most likely what Notepad is reading. Also, does it matter that you're copying with "format" but pasting with "mydatatype"?
Could it be that text parameter always has a value and gets set. Then possibly the second if the one that would set the object does not get executed. Or if it does since the data was set in the first if statement the second set fails to set it correctly.
My recommendation would be to walk the code in the debugger during the copy operation.
Before the paste use GetDataObject().GetFormats() to enumerate the list of formatting codes.
Perhaps your using the wrong one.. just an idea
Try using reflection like this:
private static T TryGetClipboardData<T>(IDataObject clipboardData, string dataFormat)
{
System.Reflection.FieldInfo fieldInfo = clipboardData.GetType().GetField("innerData", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var outerData = fieldInfo.GetValue(clipboardData);
if (outerData == null)
{
return default(T);
}
fieldInfo = outerData.GetType().GetField("innerData", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var innerData = fieldInfo.GetValue(outerData);
if (innerData is System.Runtime.InteropServices.ComTypes.IDataObject)
{
// It is (probably) necessary to wrap COM IDataObject to Windows.Forms.IDataObject
System.Windows.Forms.DataObject wrappedDataObject = new System.Windows.Forms.DataObject(innerData);
var data = wrappedDataObject.GetData(dataFormat);
if (data is T)
{
return (T)data;
}
}
return default(T);
}
I suspect the COM object of your data in the Clipboard had a difficult time converting itself to the format you specified. I'm also playing safe with the input format string so that it is registered as a proper clipboard format.
HTH

Categories