ADOX Multiple-step OLE DB operation generated errors - c#

I have to make a program that turns off all Unicode compression and all "allow zero length" in an access database (.mdb) .
The method for turning off Allow Zero Length works very well. However, the method for turning off Unicode compression does not work at all and returns the following exception:
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.
Any clue on how to solve this ?
private void TurnOffUnicodeCompressionInField(ADOX.CatalogClass catalogClass, String tableName, String field)
{
ADOX.Column column = catalogClass.Tables[tableName].Columns[field];
ADOX.Property prop = column.Properties["Jet OLEDB:Compressed UNICODE Strings"];
prop.Value = true;
}
private void TurnOffAllowZeroLengthInAllFields(ADOX.CatalogClass catalogClass, String tableName)
{
foreach (ADOX.Column column in catalogClass.Tables[tableName].Columns)
column.Properties["Jet OLEDB:Allow Zero Length"].Value = false;
}
private void MyButton_Click(object sender, EventArgs e)
{
String filePath = "";
OpenFileDialog ofd = new OpenFileDialog();
DialogResult result = ofd.ShowDialog();
if (result == DialogResult.OK)
{
filePath = ofd.FileName;
ADOX.CatalogClass catDatabase = new ADOX.CatalogClass();
catDatabase.let_ActiveConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath);
// SoftwareTable
TurnOffAllowZeroLengthInAllFields(catDatabase,"Software");
TurnOffUnicodeCompressionInField(catDatabase, "Software", "Description");
TurnOffUnicodeCompressionInField(catDatabase, "Software", "Name");
}
}

You should check your strings for characters that do not have appropriate UNICODE values, these can often be introduced when text is copied and pasted from an application like MS Word. Specifically the "smart quotes" often cause issues.
Also take a look at the following thread (although it is in C++) Discussion on ADOX Property Usage in C++.
Are you able to loop through the properties and display their current values?

Related

File.Exists(Path) always return false when get 'string (Path)' from text file

I write codes to receive the path of a text file and store it in a string variable that I declare in public.
Then I want to know if the file exists or not by using
System.IO.File.Exists(pathoffile)
But it always returns false even though there is a file.
And then when I try to add the string path directly like this
public string propertyfile = #"C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt"
The function
System.IO.File.Exists(pathoffile)
return true
I already check the receive path(string) that I read from the text file. By cutting off "\n" and "\r" and using trim() too.But it still returns false.
Have I missed something? What difference between these two?. I'm too new to this c#. I'm very bad at this sorry in advance.
Here are my codes
public string pathfromread, partnumber, pathfile, portname, partnofromserial,propertypathfile; //Declare Variables
public string propertyfile = #"C:\Users\PFA Wongsawat\Desktop\Properties.txt";
public string pathoffile ;
public string backuppath ;
public string pdffolderpath ;
private void propertyget()
{
if (File.Exists(propertyfile))
{
StreamReader readpropertyfile = new StreamReader(propertyfile);
string readproperty;
while ((readproperty = readpropertyfile.ReadLine()) != null)
{
string[] propertyfromread = readproperty.Trim().Split('=');
if (propertyfromread.GetValue(0).ToString() == "pathoffile")
{
pathoffile = propertyfromread.GetValue(1).ToString();
pathoffile = pathoffile.Replace("\n", "").Replace("\r", "");
MessageBox.Show(pathoffile, "path file");
}
else if ((propertyfromread.GetValue(0).ToString() == "backuppath"))
{
backuppath = propertyfromread.GetValue(1).ToString();
backuppath = backuppath.Replace("\n", "").Replace("\r", "");
MessageBox.Show(backuppath);
}
else if ((propertyfromread.GetValue(0).ToString() == "pdffolderpath"))
{
pdffolderpath = propertyfromread.GetValue(1).ToString();
pdffolderpath = pdffolderpath.Replace("\n", "").Replace("\r", "");
MessageBox.Show(pdffolderpath);
}
else if ((propertyfromread.GetValue(0).ToString() == "portname"))
{
portname = propertyfromread.GetValue(1).ToString();
portname = portname.Replace("\n", "").Replace("\r", "");
MessageBox.Show(portname);
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
propertyget();
dv = dt.DefaultView; //set dv index count to != 0 to prevent error from null input when click on remove button
if (System.IO.File.Exists(pathoffile))//Check if file exist or not
{
}
else
{
try
{
MessageBox.Show("Database Text File Missing. Please Select New File", "Database Text File Missing", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
OpenFileDialog regispath = new OpenFileDialog();
regispath.Title = "Select Database Text File (part_no_and_path_list.txt)";
regispath.Multiselect = false;
regispath.Filter = "Text file (*.txt)|*.txt";
regispath.RestoreDirectory = true;
regispath.ShowDialog();
pathfile = regispath.FileName;
File.Copy(pathfile, pathoffile);
}
catch
{
And this is my property text file
pathoffile=#"C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt"
backuppath=#"C:\Users\PFA Wongsawat\Documents\part_no_and_path_list.txt"
pdffolderpath=#"C:\Users\PFA Wongsawat\Downloads\"
portname=COM3
In this case the result always a messageBox showing "Database Text File Missing. Please Select New File"
Thank you and sorry for my bad English.
You don't put #" and " in the text file, you only put them in the code because that's how the c# compiler knows they're strings (and knows not to interpret slashes as an escape character)
Just make your text file look like:
pathoffile=C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt
I also recommend you use:
Split(new []{'='}, 2)
This will allow you to use = in your path, by making split return a maximum of 2 split values; any = that are legitimately in the path would be preserved
Actually I recommend you use one of the various built in settings mechanisms that c# has; we haven't needed to read and write our own configuration files for about 25 years
If you really do want to continue rolling your own you can reduce your code massively by using a dictionary
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class Settings{
private Dictionary<string,string> _conf = new Dictionary<string,string>();
public string PathOfFile {
get => _conf["pathoffile"];
}
public void ReadConfig(){
File.ReadAllLines("conf.txt").ToDictionary(
x => x.Split(new[]{'='},2)[0],
x => x.Split(new[]{'='},2)[1]
);
}
}
Yep, it's all you need. Every time you want to add another setting, add another property (like public string PathOfFile), add another love to the file and make sure the string in the property matches the line in the file
In other areas, please read up on c# naming conventions; PublicThingsAreNamedLikeThis, _privateLikeThis, localLikeThis, neverlikethis
Thank you I've already solved this problem
By remove "#" and '""' from path in the property text file like this.
pathoffile=C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt
backuppath=C:\Users\PFA Wongsawat\Documents\part_no_and_path_list.txt
pdffolderpath=C:\Users\PFA Wongsawat\Downloads\
portname=COM3
The reason I can't see this because I debug the program by seeing the result in message box and it not match with the real one. Thank you.

String appears differently depending on use scenario

Getting some odd behavior with JSON data which is being loaded into an observablecollection.
Here's an example of the JSON import, and how my folder path is shown.
{
"projectNumber":"16000",
"projectName":"Sample Project",
"Directory":"#\"C:\\Users\"", }
So far I've been able to use the data as expected after loading into my observablecollection. For example, the messagebox shows (selectedfolder) in the messagebox as intended: #"C:\Users"
This is the path I want my treeview to use. Oddly, it's not using that but instead uses the original path format from my JSON import instead ("#\"C:\Users\"") and throws an "Illegal characters in path" error.
private void ListDirectory(TreeView treeView, string path)
{
treeView.Items.Clear();
var rootDirectoryInfo = new DirectoryInfo(path);
treeView.Items.Add(CreateDirectoryNode(rootDirectoryInfo));
}
private static TreeViewItem CreateDirectoryNode(DirectoryInfo directoryInfo)
{
var directoryNode = new TreeViewItem { Header = directoryInfo.Name };
foreach (var directory in directoryInfo.GetDirectories())
directoryNode.Items.Add(CreateDirectoryNode(directory));
foreach (var file in directoryInfo.GetFiles())
directoryNode.Items.Add(new TreeViewItem { Header = file.Name });
return directoryNode;
}
private void button_Click(object sender, RoutedEventArgs e)
{
Project selectedProject = comboBox.SelectedItem as Project;
selectedfolder = selectedProject.Directory.ToString();
MessageBox.Show(selectedfolder);
if (selectedProject != null)
{
this.ListDirectory(treeView, selectedfolder);
}
Anybody see what I'm missing here, and why the same string would appear differently depending on how it's being used?
The #"" string literal is used to help write code that has strings with backslashes in it. This bit of code, for instance, contains a reference to a valid path, and the #"" bit just tells the C# compiler to treat backslashes differently than normal C-style strings:
string example1 = #"C:\Users";
Debug.WriteLine(example1); // Outputs C:\Users
// This works
var temp1 = new DirectoryInfo(example1);
Once you actually embed the #"" bit in a string, you end up with a string that contains # and " characters in it, which isn't going to be a valid path on Windows.
string example2 = "#\"C:\\Users\"";
Debug.WriteLine(example2); // Outputs #"C:\Users"
// This throws an exception
var temp2 = new DirectoryInfo(example2);
In other words: Using #"" is fine for C# code, but for a JSON object, you'll need to change your JSON text to be something like this, using \ to escape characters, so it's a valid path after the JSON deserializer finishes parsing the string:
{
"projectNumber":"16000",
"projectName":"Sample Project",
"Directory":"C:\\Users",
}
That was clearly the answer. Thanks so much, Anon! What was throwing me off was how the string showed in a messagebox exactly how I would use it in a path reference. Newbie mistake!

Deserializing SSIS data from DTSX file

I am trying to deserialize XML from SSIS DTSX files. I have found the XSD files which I think are needed, found here: https://msdn.microsoft.com/en-us/library/gg587628%28v=sql.105%29.aspx. I have used xsd2code plugin for VS to create objects from the XSDs.
The problem: I am able to deserialize into these objects, but almost no actual data gets pulled in from the DTSX files.
In the code below, I have placed a break point at the WriteLine() command in Parse_XML() and looked at the contents of the two ExecutableTypePackage objects (executables and exec). Both have the same contents:
The property ExecutableType gets set to "SSIS.Package.3"
The Property collection (List<ExecutableTypePackageProperty>) has one element; its Name property is set to "PackageFormatVersion" and Value property is set to "6".
That's all. While those values are correct, there's a lot more data in the file that's not getting pulled in. But I get no warnings nor exceptions.
Admittedly, I don't have much experience with XML, and using the serialization methods is very new to me, but I have used them for validating the XML structure of report files (RDL), and never ran across any such issues. I have been beating my head against the wall for 2 full days on this now, and I am not making any progress. I have searched every which way I can think of for answers on this, but I don't find anyone else having this problem.
string file = null;
public Form1()
{
InitializeComponent();
}
private void Run_btn_Click(object sender, EventArgs e)
{
Parse_XML();
MessageBox.Show("Done!");
}
private void Parse_XML()
{
TextReader tr = new StreamReader(file);
XmlSerializer serializer = new XmlSerializer(typeof(DTSX.ExecutableTypePackage));
DTSX.ExecutableTypePackage executables = (DTSX.ExecutableTypePackage)serializer.Deserialize(tr);
DTSX.ExecutableTypePackage exec = DTSX.ExecutableTypePackage.Deserialize(File.ReadAllText(file));
MessageBox.Show(String.Format("Found {0} executables in package.", exec.Executable.Count));
Console.WriteLine("Done loading root object.");
}
private void File_btn_Click(object sender, EventArgs e)
{
int text_size = -1;
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
file = openFileDialog1.FileName;
try
{
string text = File.ReadAllText(file);
text_size = text.Length;
File_txtbx.Text = file;
}
catch (IOException)
{
}
}
Console.WriteLine(file);
Console.WriteLine(text_size);
Console.WriteLine(result);
}

C# - my ReadLine() gives me a null value when I should get a string

Solved - Accidentally wiped the actual file of data but the ide doesn't update that file unless you reopen it so I thought the data was still in there.
I'm working on a project in C# that reads in a fake inventory and then transactions to go with that inventory in another class. I know the code is quite messy at the moment, i'm just trying to figure out one thing specifically.
this code here will read in my file "Inventory.in", check if the file exists(which it does) and then start my streamreader and readline into a string.
private void btnFill_Click(object sender, EventArgs e)
{
string strInputLine;
string inFile = "Inventory.in";
StreamReader iSR;
InvRec currInvent;
if (File.Exists(inFile))
{
iSR = new StreamReader(inFile);
strInputLine = iSR.ReadLine();
while (strInputLine != null)
{
all of it isn't there but the point of emphasis is that the
"strInputLine = iSR.ReadLine();"
does indeed give me the correct value from that file.
now moving on to my question, the second block of code from another button is below:
private void btnProcess_Click(object sender, EventArgs e)
{
string strInputVal;
string inFileName = "Transactions.in";
TransRec currTrans;
StreamReader iSR2;
transListClass transactionList = new transListClass();
InvRec inventItem = inventoryList.Retrieve();
if (File.Exists(inFileName))
{
iSR2 = new StreamReader(inFileName);
strInputVal = iSR2.ReadLine();
while (strInputVal != null)
{
my problem lies when I try and do my ReadLine() into iSR2. it gives me null instead of the value from the file I'm supposed to get. Everything is the same otherwise, it just refuses to give me the correct value. I'm following the debugger in Visual Studio 2010, so I know the file is found and exists, I see it being opened, just a null value instead of my string I need.
Thank you to anybody in advance, I appreciate it.
-Anthony
edit:
the second block of code is supposed to read from "Transactions.in" instead of the first one that reads from "Inventory.in"
Important edit:
I have noticed when i changed "Transactions.in" to "Inventory.in" in the second block of code for the process button, it reads the values from Inventory.in and gives me a proper string unlike null from Transactions.in. The file is found and is just a text file named Transactions.in that was provided by my teacher, nobody else had a problem with it.

Lookup from CSV

I have a CSV file in this format:
"Call Type","Charge Type","Map to"
"51","","Mobile SMS"
"52","","Mobile SMS"
"DD","Local Calls","Local Calls"
"DD","National Calls","National Calls"
First two columns are the "source information" that my C# will insert, and the last column is what it will return.
Currently what I am doing is a switch statement hardcoded in c#.
var File001 = from line in File.ReadLines(bill_file)
let l = line.Split(',')
select new
{ CallType = ICD_map(l[5],l[3])}
where
l[5] = "51";
l[3] = "";
private static string ICD_map(string call_type_description, string call_category,)
{
case "51":
case "52":
return "Mobile SMS";
default:
return "Unknown";
}
I want this to be an expandable list thus my new method is to load the mapping table from a csv file. Can you suggest any improvements to this method to make my definition library expandable (hoping CSV file okay for this purpose, it is only 100 lines long so far, so not concerned about memory management).
What I have tried so far is:
class ICD_Map2
{
private string call_type;
private string charge_type;
private string map_to;
// Default constructor
public ICD_Map2() {
call_type = "Unknown";
charge_type = "Unknown";
map_to = "Unknown";
}
// Constructor
public ICD_Map2(string call_type, string charge_type, string map_to)
{
this.call_type = call_type;
this.charge_type = charge_type;
this.map_to = map_to;
}
}
List<ICD_Map2>maps = new List<ICD_Map2>();
private void button2_Click(object sender, EventArgs e)
{
// Start new thread to create BillSummary.csv
button1.Enabled = false;
maps.Clear();
//load mapping file
var reader = new StreamReader(File.OpenRead(#"Itemised_Call_Details_Map.csv"));
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
maps.Add(new ICD_Map2(values[0].Replace("\"",""), values[1].Replace("\"",""), values[2].Replace("\"","")));
textBox2.AppendText(Environment.NewLine + " Mapping: " + values[0].Replace("\"", "") + " to " + values[1].Replace("\"", ""));
}
I have loaded the CSV file to my program but I am unable to do the lookup from LINQ. Can you tell me the next process.
Open to any other method.
Thanks for your time.
I would suggest you to go with
http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
It will give you lots of flexibility to play around with your code.
We have been using it in our projects, and it's really helpful to have full control inplace of writing generic CSV code which is prone to errors and bugs

Categories

Resources