Printing Duplicate Records from the Data View In Acumatica - acumatica

I am trying to print all records of a data-view into a file using a for loop in my customization in Acumatica. Unfortunately I am ending up with printing the first record everytime resulting into duplication of records, Unable to track where I am going wrong....Please Assist
Here Goes my Code......
public class MayBankGIROProcess : PXGraph<MayBankGIROProcess>
{
public PXSelect<MayBankGIRO> Document; //This is my Data View
public PXAction<MayBankGiroFilter> createTextFile;
[PXUIField(DisplayName = "Create Text File")]
[PXButton()]
public virtual IEnumerable CreateTextFile(PXAdapter adapter)
{
List<string> myList = new List<string> { };
foreach (MayBankGIRO dacRecord in this.Document.Select()) //this is the loop which is taking the data records.
{
myList.Add(dacRecord.ReordType+ "|"+ dacRecord.CustomerReferenceNumber+ "|"+ dacRecord.ClientBatchID+ "|");
// The above line is printing only the first record of the data view everytime .
}
string filename = "DAWN" + ".txt";
Download(myList, filename);
return adapter.Get();
}
public static void Download(List<string> lines, string name) //method generating file
{
var bytes = default(byte[]);
using (MemoryStream stream = new MemoryStream())
{
StreamWriter sw = new StreamWriter(stream);
foreach (string line in lines)
{
sw.WriteLine(line);
}
stream.Position = 0;
bytes = stream.ToArray();
sw.Close();
};
PX.SM.FileInfo textDoc = new PX.SM.FileInfo(name, null, bytes);
if (textDoc != null)
{
throw new PXRedirectToFileException(textDoc, true);
}
else
{
PXTrace.WriteInformation("Could not generate file");
}
}
}
[Generated Text File with all duplicate Record][1]
[1]: https://i.stack.imgur.com/Kllmk.png
[Original Record from database][2]
[2]: https://i.stack.imgur.com/Rbr9k.png

This usually happens when the report is pulling from a SQL View DAC which doesn't have unique key defined. Add IsKey=True on DAC fields until the SQL view is pulling unique record and the error should go away.

Related

WordProcessingDocument not preserving whitespace

I'm writing a C# program using XML and Linq that reads in data from tables stored in a word document and inserts it into an excel spreadsheet. The code I have so far does this, however it does not preserve any new lines (in the word doc the "new line" is done by pressing the enter key). Using the debugger, I can see that the new lines aren't even being read in. For example, if the text I want to copy is:
Something like this
And another line
And maybe even a third line
It gets read in as:
Something like thisAnd another lineAnd maybe even a third line
I can't separate the lines by a character as the words could be anything. This is what I have so far:
internal override Dictionary<string, string> GetContent()
{
Dictionary<string, string> contents = new Dictionary<string, string>();
using (WordprocessingDocument doc = WordprocessingDocument.Open(MainForm.WordFileDialog.FileName, false))
{
List<Table> tables = doc.MainDocumentPart.Document.Descendants<Table>().ToList();
foreach (Table table in tables)
{
TableRow headerRow = table.Elements<TableRow>().ElementAt(0);
TableCell tableSectionTitle;
try
{
tableSectionTitle = headerRow.Elements<TableCell>().ElementAt(0);
}
catch (ArgumentOutOfRangeException)
{
continue;
}
List<TableRow> rows = table.Descendants<TableRow>().ToList();
foreach (TableRow row in rows)
{
TableCell headerCell = row.Elements<TableCell>().ElementAt(0);
if (headerCell.InnerText.ToLower().Contains("first item"))
{
contents.Add("first item", row.Elements<TableCell>().ElementAt(1).InnerText);
}
else if (headerCell.InnerText.ToLower().Contains("second item:"))
{
char[] split = { ':' };
Int32 count = 2;
string str = row.Elements<TableCell>().ElementAt(0).InnerText;
String[] newStr = str.Split(split, count, StringSplitOptions.None);
contents.Add("second item:", newStr[1]);
}
**continues for many more else if statements**
else
{
continue;
}
}
}
return contents;
}
}
I'm new to using XML, so any help would be appreciated!

How fix System.FormatException reading data from text file to a listbox

My code takes data from form application and displays the result in a listbox and save the data in a file. When next I load the code it should read the data from the file and populate the listbox. I am have a System.FormatException Input string not in correct format.
The code works until I am ready to read the file. I have removed the whitespaces and the dollar sign but the problem is still there. Please any help will be appreciated.
My FileIO class code below
public static class FileIO
{
const string path = "Customers.txt";
// writes data from the array to the file
public static void WriteData(List<Customer> customers)
{
FileStream fs = null;
StreamWriter sw = null;
try
{
// open the file for writing; overwrite old content
fs = new FileStream(path, FileMode.Create, FileAccess.Write);
sw = new StreamWriter(fs);
// write data
foreach (Customer item in customers)
sw.WriteLine(item.DisplayCustomersInfo("|"));
}
catch (Exception ex)
{
MessageBox.Show("Error while writing to the file: " +
ex.Message, ex.GetType().ToString());
}
finally
{
if (sw != null) sw.Close(); // also closes fs
}
}
// reads data from the file, puts in a list, and returns it
public static List<Customer> ReadData()
{
List<Customer> customers = new List<Customer>();
FileStream fs = null;
StreamReader sr = null;
string line; // for reading
string[] columns; // result from splitting the line
// open the file for reading and read number into data
try
{
fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read);
sr = new StreamReader(fs);
while (!sr.EndOfStream) // while there is data in the file
{
line = sr.ReadLine(); // read the next line
line.Trim();
columns = line.Split(','); // split line into substring from line with comma delimiters
Customer c = new Customer(Convert.ToInt32(columns[0]), columns[1], Convert.ToChar(columns[2]),
Convert.ToDecimal(columns[3].Remove(0, 1)));//this is where I think the problem is.
customers.Add(c);
}
}
catch (FormatException)
{
MessageBox.Show("File contains bad format data. Aborting reading");
}
catch (Exception ex)
{
MessageBox.Show("Error while reading the file: "
+ ex.Message, ex.GetType().ToString());
}
finally
{
// close the file if open
if (sr != null) sr.Close(); //file stream gets closed too
}
return customers;
}
}
Below is the text file.
12345|RRRRR|R|$58.05
12345|RRRRR|R|$58.05
12345|RRRRR|R|$58.05
12345|RRRRR|R|$58.05
12345|RRRRR|R|$58.05
12345|CCCCC|C|$60.05
12345|CCCCC|C|$60.05
12345|CCCCC|C|$60.05
12345|CCCCC|C|$60.05
12345|CCCCC|C|$60.05
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
12345|IIIII|I|$116.09
I have used , and ; as delimiters prior to using |.
I expect to read data from the file and populate the listbox and add more data.

System.OutOfMemoryException: Exception of Type 'System.OutOfMemory' was thrown

private List<T> ReadCurrentFile(string currentExtractedFile, PurgingDetails purgingParams)
{
List<T> thinLogDoList = new List<T>();
using (StreamReader sr = new StreamReader(currentExtractedFile))
{
string currentLine = string.Empty;
Dictionary<string, string> ColumnNamesDictionary = null;
while ((currentLine = sr.ReadLine()) != null)
{
if (currentLine.IsNotNullOrEmpty() && currentLine.Contains("Æ"))
{
string[] columnNames = currentLine.Split(new char[] { 'Æ' });
ColumnNamesDictionary = FillColumnNameDictionary(columnNames);
if (CheckForValidConditions(ColumnNamesDictionary, purgingParams))
{
thinLogDoList.Add(FillThinLogDO(ColumnNamesDictionary));
}
}
}
}
return thinLogDoList;
}
(Above code is for Reading a File and adding data to the List by filling the object.)
The function is reading file of size 10 MB which is inside a zip file, first I am extracting the zip files, then reading the data, using this function and storing it into List and then deleting the extracted zip files. It is working for approximately 6L(6,00,000) Data but above that data it throws exception.
I want to read More data 10L(10,00,000) how should I do that ?
Do not return a list. Instead, use yield return to just run through the data:
private IEnumerable<i1LogThinDO> ReadCurrentFile(string currentExtractedFile,
PurgingDetails purgingParams)
{
using (StreamReader sr = new StreamReader(currentExtractedFile))
{
string currentLine = string.Empty;
Dictionary<string, string> ColumnNamesDictionary = null;
while ((currentLine = sr.ReadLine()) != null)
{
if (currentLine.IsNotNullOrEmpty() && currentLine.Contains("Æ"))
{
string[] columnNames = currentLine.Split(new char[] { 'Æ' });
ColumnNamesDictionary = FillColumnNameDictionary(columnNames);
if (CheckForValidConditions(ColumnNamesDictionary, purgingParams))
{
yield return FillThinLogDO(ColumnNamesDictionary);
}
}
}
}
}
This way, the ball is in the caller's yard. The caller must be able to process the data returned from this method without keeping them all in memory. This could mean that you have to redesign the calling methods as well, but it would bring a huge cut down in memory footprint of the application if you could do all the processing without keeping the data in memory.

codenameone - Storage file doesn't delete

I've added storage file to my codenameone application. In some event I wanna delete specific storage file and recreate it with some old filtered data and new data. It doesn't work well on deletion.
First I create method for clear storage file in StorageManager class:
public void clearData(String pStorageTable){
Storage.getInstance().deleteStorageFile(pStorageTable);
}
In other class I use this method like this:
// load all data of specific storage file
// ...
new DBManager().clearData(ThreeTrans.DB_NAME);
// write old data with filtering of specific ID and new data
// ...
here is method of write data:
public void write(ThreeTrans pTT){
if(store == null) {
store = Storage.getInstance();
}
DB_NAME = "TT";
if(!store.exists(DB_NAME)) {
Hashtable depHash = new Hashtable();
String k = "1" + pTT.getNumber();
depHash.put(k, pTT.toString());
store.writeObject(DB_NAME, depHash);
}
else {
Hashtable depHash = (Hashtable)store.readObject(DB_NAME);
if (!depHash.containsValue(pTT.getNumber())) {
String k = String.valueOf(getLastKeyNumber());
depHash.put(k, pTT.toString());
store.writeObject(DB_NAME, depHash);
}
}
}
at first I was using this method for delete storage file:
public void clearData(String pStorageTable){
if(store == null) {
store = Storage.getInstance();
}
for (String str : store.listEntries()) {
if(str.toLowerCase().startsWith(pStorageTable)) {
store.deleteStorageFile(str);
}
}
}
and after this problem this method changed to this;
public void clearData(String pStorageTable){
Storage.getInstance().deleteStorageFile(pStorageTable);
}
I'm assuming that you didn't invoke close() on the output stream or the input stream working with the file and there is still a lock on the file. This is usually the case for such issues.

In J2ME, How to re-index records in recordstore after deleting any record

I am developing a Location-based J2ME app & in that I'm using RMS to store data.
In RecordStore when I delete any record, the underlying records doesn't get re-indexed. For example, if I have 5 records & I delete record no.2 then record ids will be {1, 3, 4, 5}. But I want record ids after deletion to be {1, 2, 3, 4}. How should I do this??? Because recordId is playing an important role in my app to retrieve & update the record.
You need to change your application logic. ID is just for identification, and not for sorting. Because it is for identification, it must remains the same.
Very often the easiest thing to do is to read and write the whole recordstore at once.
So, since you've said that your record store is basically small (not that much data), I would recommend simply adding your own custom id field to each record. As Meier said, the RMS record id is not really meant to be recalculated, and changed, once a record has been created. So, I would use your own.
If each of your records contain:
boolean isMale
int age
String firstName
then, I would simply add another field at the start of each record:
int id
It makes your records a little bigger, but not much (4 bytes/record). If you'll have less than 64k records, then you could also use a short for the id, and save a couple bytes.
Here's an example (adapted from this IBM tutorial), of reading, writing, and deleting with this kind of record:
private RecordStore _rs;
// these next two methods are just small optimizations, to allow reading and
// updating the ID field in a record without the overhead of creating a new
// stream to call readInt() on. this assumes the id is a 4 byte int, written
// as the first field in each record.
/** Update one record with a new id field */
private static final void putIdIntoRecord(int id, byte[] record) {
// we assume the first 4 bytes are the id (int)
record[0] = (byte)(id >> 24);
record[1] = (byte)(id >> 16);
record[2] = (byte)(id >> 8);
record[3] = (byte)id;
}
/** Get the id field from one record */
private static final int getIdFromRecord(byte[] record) {
// we assume the first 4 bytes are the id (int)
return ((0xFF & record[0]) << 24) |
((0xFF & record[1]) << 16) |
((0xFF & record[2]) << 8) |
(0xFF & record[3]);
}
/** delete a record with the given (custom) id, re-indexing records afterwards */
private void delete(int idToDelete) {
try {
RecordEnumeration enumerator = _rs.enumerateRecords(new IdEqualToFilter(idToDelete),
null, false);
_rs.deleteRecord(enumerator.nextRecordId());
// now, re-index records after 'idToDelete'
enumerator = _rs.enumerateRecords(new IdGreaterThanFilter(idToDelete), null, true);
while (enumerator.hasNextElement()) {
int recordIdToUpdate = enumerator.nextRecordId();
byte[] record = _rs.getRecord(recordIdToUpdate);
// decrement the id by 1
int newId = getIdFromRecord(record) - 1;
// copy the new id back into the record
putIdIntoRecord(newId, record);
// update the record, which now has a lower id, in the store
_rs.setRecord(recordIdToUpdate, record, 0, record.length);
}
} catch (RecordStoreNotOpenException e) {
e.printStackTrace();
} catch (InvalidRecordIDException e) {
e.printStackTrace();
} catch (RecordStoreException e) {
e.printStackTrace();
}
}
/** generate some record store data ... example of writing to store */
public void writeTestData()
{
// just put 20 random records into the record store
boolean[] booleans = new boolean[20];
int[] integers = new int[20];
String[] strings = new String[20];
for (int i = 0; i < 20; i++) {
booleans[i] = (i % 2 == 1);
integers[i] = i * 2;
strings[i] = "string-" + i;
}
writeRecords(booleans, integers, strings);
}
/** take the supplied arrays of data, and save a record for each array index */
public void writeRecords(boolean[] bData, int[] iData, String[] sData)
{
try
{
// Write data into an internal byte array
ByteArrayOutputStream strmBytes = new ByteArrayOutputStream();
// Write Java data types into the above byte array
DataOutputStream strmDataType = new DataOutputStream(strmBytes);
byte[] record;
for (int i = 0; i < sData.length; i++)
{
// Write Java data types
strmDataType.writeInt(i); // this will be the ID field!
strmDataType.writeBoolean(bData[i]);
strmDataType.writeInt(iData[i]);
strmDataType.writeUTF(sData[i]);
// Clear any buffered data
strmDataType.flush();
// Get stream data into byte array and write record
record = strmBytes.toByteArray();
_rs.addRecord(record, 0, record.length);
// Toss any data in the internal array so writes
// starts at beginning (of the internal array)
strmBytes.reset();
}
strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
/** read in all the records, and print them out */
public void readRecords()
{
try
{
RecordEnumeration re = _rs.enumerateRecords(null, null, false);
while (re.hasNextElement())
{
// Get next record
byte[] recData = re.nextRecord();
// Read from the specified byte array
ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData);
// Read Java data types from the above byte array
DataInputStream strmDataType = new DataInputStream(strmBytes);
// Read back the data types
System.out.println("Record ID=" + strmDataType.readInt());
System.out.println("Boolean: " + strmDataType.readBoolean());
System.out.println("Integer: " + strmDataType.readInt());
System.out.println("String: " + strmDataType.readUTF());
System.out.println("--------------------");
strmBytes.close();
strmDataType.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
Here, I make use of a couple small RecordFilter classes, to use when searching the record store:
/** helps filter out records greater than a certain id */
private class IdGreaterThanFilter implements RecordFilter {
private int _minimumId;
public IdGreaterThanFilter(int value) {
_minimumId = value;
}
public boolean matches(byte[] candidate) {
// return true if candidate record's id is greater than minimum value
return (getIdFromRecord(candidate) > _minimumId);
}
}
/** helps filter out records by id field (not "recordId"!) */
private class IdEqualToFilter implements RecordFilter {
private int _id;
public IdEqualToFilter(int value) {
_id = value;
}
public boolean matches(byte[] candidate) {
// return true if candidate record's id matches
return (getIdFromRecord(candidate) == _id);
}
}

Resources