Remove the string after '-' and group remaining string and pivot column - c#

Here is my actual data in Excel, which I am successfully able to read in DataGridView in C# Windows Application.
Test | Energy |
---------------------
C018-3L-1 | 113 |
C018-3L-2 | 79 |
C018-3L-3 | 89 |
C018-3L-4 | 90 |
C018-3L-5 | 95 |
C021-3T-1 | 115 |
C021-3T-2 | 100 |
But now I want this data in DataGridView in below Format from excel file:
Test |Energy-1|Energy-2|Energy-3 |
------------------------------------
C018-3L |113 |79 |89 |
C018-3L |90 |95 |NULL |
C021-3T |115 |100 |NULL |
Here is my code:
private void TensileEnergyData_Load(object sender, EventArgs e)
{
try
{
string sourcefilepath = ConfigurationManager.AppSettings["FilePath"].ToString();
string[] files = Directory.GetFiles(sourcefilepath, "*.xlsx");
foreach (string s in files)
{
string excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + s + ";Extended Properties='Excel 12.0;HDR=YES';";
// Create Connection to Excel Workbook
using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
{
connection.Open();
da = new OleDbDataAdapter("Select Test, Energy FROM [Sheet1$]", connection);
da.Fill(dtExcelData);
connection.Close();
}
}
}
catch (Exception ex)
{
objDAL.SendExcepToDB(ex, "TensileEnergyData_Load");
MessageBox.Show("Fail to read data...!!");
}
dataGridView1.Visible = true;
dataGridView1.DataSource = dtExcelData;
}
How can I achieve this using Group By?

I'll provide a SQL-Server based answer, as your very related question asked for this. Here you did not tag your question with [sql-server] at all... Hope this helps...
This is a very good reason, why you should never ever put more than one content in one column. Store this in separate columns and this will be much easier.
Further more, this smells a bit... Such issues should rather be solved in your presentation layer.
Nevertheless this can be done:
DECLARE #tbl TABLE(Test VARCHAR(100),Energy INT);
INSERT INTO #tbl VALUES
('C018-3L-1',113)
,('C018-3L-2',79)
,('C018-3L-3',89)
,('C018-3L-4',90)
,('C018-3L-5',95)
,('C021-3T-1',115)
,('C021-3T-2',100);
SELECT p.*
FROM
(
SELECT B.Code
,(B.Number-1)/3 AS Line
,CONCAT('Energy-',CASE B.Number % 3 WHEN 0 THEN 3 ELSE B.Number % 3 END) AS ColumnName
,Energy
FROM #tbl t
CROSS APPLY(SELECT LEN(t.Test) - CHARINDEX('-',REVERSE(t.Test))) A(PosLastHyphen)
CROSS APPLY(SELECT LEFT(t.Test,PosLasthyphen) AS Code
,CAST(SUBSTRING(t.Test,PosLastHyphen+2,10) AS INT) AS Number) B
) tbl
PIVOT
(
MAX(Energy) FOR ColumnName IN([Energy-1],[Energy-2],[Energy-3])
) p
ORDER BY Code,Line;
The result
+---------+------+----------+----------+----------+
| Code | Line | Energy-1 | Energy-2 | Energy-3 |
+---------+------+----------+----------+----------+
| C018-3L | 0 | 113 | 79 | 89 |
+---------+------+----------+----------+----------+
| C018-3L | 1 | 90 | 95 | NULL |
+---------+------+----------+----------+----------+
| C021-3T | 0 | 115 | 100 | NULL |
+---------+------+----------+----------+----------+
Some explanations
I use the CROSS APPLY to compute the separation of your code and the running number. Then I use the integer division to calculate the group and the modulo operator % to spread this in three columns.

Related

How does Apache Ignite supports partitioning?

I am trying to experiment with data partition in Apache Ignite using .NET thin client.
In article https://apacheignite.readme.io/docs/cache-modes it's written that in partition mode "the overall data set is divided equally into partitions and all partitions are split equally between participating nodes". So I am expecting cache with 1000 records to be splitted beetween 3 Ignite nodes equally: 333(4) on each node. But when I start 3 instances of Ignite on local machine (using platforms\dotnet\bin\Apache.Ignite.exe) I can see only that 1000 records are replicated on all nodes: 1000 same records on each node. I tried to disable backups creation: 1000 records were created only on first node. Currently I use sequental Int32 values as cache key. But even when I ran LinqExample with colocated employes (with AffinityKey) data was't splitted beetween nodes.
I also tried to experiment with cache configuration:
var cacheConfiguration = new CacheClientConfiguration(_key, cacheEntity);
cacheConfiguration.CacheMode = CacheMode.Partitioned;
cacheConfiguration.Backups = 0;
cacheConfiguration.ReadFromBackup = false;
cacheConfiguration.RebalanceMode = CacheRebalanceMode.Sync;
cacheConfiguration.RebalanceOrder = 1;
cacheConfiguration.RebalanceThrottle = TimeSpan.FromSeconds(1);
cacheConfiguration.RebalanceDelay = TimeSpan.Zero;
cacheConfiguration.RebalanceBatchSize = 1024;
var cache = _igniteClient.CreateCache<int, TEntityType>(cacheConfiguration).WithExpiryPolicy(_expiryPolicy);
Perhaps I don't understand the main concept of data partitioning implemented in Apache Ignite or Apache.Ignite.exe needs some additional configuration to support data partitioning. Execuse me if it's a simple question.
PS. I am using DBeaver to check amount of records on each node. 3 ignite instances by default uses ports 10800, 10801, 10802 for .NET client requests. So I am using localhost:10800, localhost:10801, localhost:10802 adresses in DBeaver.
To get the number of entries per node, use included Visor tool.
Go to Ignite bin directory
Start ignitevisorcmd
Use open to connect to a cluster
Type cache -a
Generated report will include table with node specifics:
Nodes for: person-cache-1(#c0)
+====================================================================================================================+
| Node ID8(#), IP | CPUs | Heap Used | CPU Load | Up Time | Size (Primary / Backup) | Hi/Mi/Rd/Wr |
+====================================================================================================================+
| 1F81F615(#n0), 127.0.0.1 | 12 | 10.26 % | 0.00 % | 00:08:15.394 | Total: 513 (513 / 0) | Hi: 0 |
| | | | | | Heap: 0 (0 / <n/a>) | Mi: 0 |
| | | | | | Off-Heap: 513 (513 / 0) | Rd: 0 |
| | | | | | Off-Heap Memory: <n/a> | Wr: 0 |
+-----------------------------+------+-----------+----------+--------------+---------------------------+-------------+
| FBCF3B0F(#n1), 127.0.0.1 | 12 | 15.23 % | 0.00 % | 00:07:46.647 | Total: 486 (486 / 0) | Hi: 0 |
| | | | | | Heap: 0 (0 / <n/a>) | Mi: 0 |
| | | | | | Off-Heap: 486 (486 / 0) | Rd: 0 |
| | | | | | Off-Heap Memory: <n/a> | Wr: 0 |
+--------------------------------------------------------------------------------------------------------------------+
According to Size(Primary/...) 999 entries are split between two nodes, with 513 entries on the first node and 486 on the second node.
Check "Primary" and not "Total"; "Total" is sum of primary entries and replicated entries from other nodes. Shown setup does not have replication, so it is equal to "Primary".
If a cluster had three nodes, and a cache had 2 replicas (so 3 copies in total), then the "Total" number on one node will be close to a total number of entries (as each node contains all entries, either as a primary node or backup node for two other nodes), "Primary" would be approximately 1/3 of the total and "Backup" would be 2/3.

FIX Reading Repeating groups

I have a FIX log file. I'm iterating on the lines, putting each string into
Message m = new Message(str, false)
Because for some reason, validation fails on the file (even the first line). Now, I see that it's a 35=X type, and 268=4 (i.e. NoMDEntries=4, so I should have 4 groups in the message)
BUT, in the debug display I am not seeing any groups. m.base._groups has a count of 0.
The string in question is:
1128=9 | 9=363 | 35=X | 49=CME | 34=3151 | 52=20121216223556363 | 75=20121217 | 268=4 | 279=0 | 22=8 | 48=43585 | 83=902 | 107=6EH3 | 269=4 | 270=13186 | 273=223556000 | 286=5 | 279=0 | 22=8 | 48=43585 | 83=903 | 107=6EH3 | 269=E | 270=13186 | 271=9 | 273=223556000 | 279=0 | 22=8 | 48=43585 | 83=904 | 107=6EH3 | 269=F | 270=13185 | 273=223556000 | 279=1 | 22=8 | 48=43585 | 83=905 | 107=6EH3 | 269=0 | 270=13186 | 271=122 | 273=223556000 | 336=0 | 346=10 | 1023=1 | 10=179 |
Another thing is how do I read the groups? Instinctively, I want to do something like
for (int i = 1; i <= noMDEntries; i++) {
Group g = m.GetGroup(i);
int action = Int32.Parse(g.GetField(279));
....
}
But that's not how it works and I haven't found documentation with better explanations.
Thanks for the help,
Yonatan.
From your code snippets, I think you're using QuickFIX/n, the native C# implementation, so I will answer accordingly.
1) Your message construction is failing because you didn't provide a DataDictionary.
Use Message::FromString instead:
Message m = new Message();
m.FromString(msg_str, false, data_dic, data_dic, someMsgFactory);
Even better, use MarketDataIncrementalRefresh::FromString to get the right return type.
You can see some uses of this function here:
https://github.com/connamara/quickfixn/blob/master/UnitTests/MessageTests.cs
2) To read groups... well, QF/n has a doc page on that, which I think explains it pretty well.
http://quickfixn.org/tutorial/repeating-groups

Possible to add two columns together and group by that column using linq on IQueryable?

My data comes from IQueryable that looks like the following table when I return all of the DailyCollectionActivities.
CatType | CdDescr | CollTypeDescr | RollCasteDescr | TIFDescr | TADescr | Amount
--------------------------------------------------------------------------------
Cat 1 | Cd 1 | CollType 233 | Roll Caste 234 | TIF 2344 | TA 2343 | 344.35
Cat 1 | Cd 1 | CollType 222 | Roll Caste 235 | TIF 2345 | TA 2344 | 355.35
Cat 2 | Cd 2 | CollType 223 | Roll Caste 236 | TIF 2346 | TA 2345 | 664.44
Cat 3 | Cd 3 | CollType 255 | Roll Caste 236 | TIF 2347 | TA 2346 | 455.34
Cat 4 | Cd 4 | CollType 266 | Roll Caste 236 | TIF 2348 | TA 2347 | 455.44
I'm trying to find out if it's possible, using linq on the IQueryable<DailyCollectionActivity> data, to add two columns together and then group on that newly created column? For example I need to figure out how to add CatType to CdDescr (CatType + '-' + CdDescr) and then group by that newly created column and sum the Amounts. Finally, I then need to take the results of that query and bind it to a RadGrid.
To make things more interesting, the user is allowed to choose which columns get added together. I could wind up with a group by clause like (CatType + '-' CdDescr), (TIFDescr + '-' + TADescr).
Is this something that I can reasonably accomplish using Linq?
say its from categories
var result = from s in (
from p in categories
select new {
TypeDesr = p.CatType+"-"+ p.CdDesr,
CollTypeDescr = p.CollTypeDescr ,
RollCasteDescr = p.RollCasteDescr,
TIFDescr = p.TIFDescr,
TADescr = p.TADescr,
Amount = p.Amount
})
group s by s.TypeDesr into r
select r;

how to get records entered in text file based on key value

I am developing windows project using c#. I have to import text file records into sqlserver 2005 db.
My question is
I want to read records from text file using student Idno.
I have an idea of read exact value from text file using strings that is finding student no:1001 value .
I want to read every student record based on particular student no? not for 1001
so I want standered code to read particular records based on student number as
my choice.
plz help me.......
my text file like this
|-----------------------------------------------|
| student no:1001 |
| address:ongole,A.P, |
| hyderabad,india. |
| ----------------------------------------------|
| stdid stdname class |
| 1 raheem mca |
| 2 sudheer mca |
| ----------------------------------------------|
| student no:1001 |
| address:ongole,A.P, |
| hyderabad,india. |
-|-------------------------------------------- |
| stdid stdname class |
| 1 raheem mca |
| 2 sudheer mca |
| ----------------------------------------------|
| student no:1002 |
| address:ongole,A.P, |
| hyderabad,india. |
------------------------------------------------|-
| student no:1003 |
| address:ongole,A.P, |
| hyderabad,india. |
-|---------------------------------------------- |
My code is
private void BtnImpstrm_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
string f = openFileDialog1.FileName;
StreamReader sr = new StreamReader(f);
string s = sr.ReadToEnd();
MessageBox.Show(s);
sr.Close();
str =s.Split('\n');
for (int i = 0; i < str.Length; i++)
{
if (str[i].ToString().Trim().ToUpper().Contains("Student NO : 1001"))
{
string[] words = str[i].Split(' ');
string output = words[word no].ToString().Trim();
string rec1 =str[line no].ToString().Trim();
string rec2 = str[line no].ToString().Trim();
MessageBox.Show(output);
MessageBox.Show(rec1);
MessageBox.Show(rec2);
}
}
}
I think your best bet would be to use StreamReader to read line-by-line and if you encounter "student ..." or something like it, read the next 7 lines to complete your record. After doing this, you will have a collection of strings, each being a unique record in the file.
Then you can parse each record individually, by splitting the string on Environment.NewLine.

How to use C# to parse a glossary into database?

This should be a simple one, but I'm a beginner with C#.
Given a glossary list in the following format:
aptitude
ability, skill, gift, talent
aqueous
watery
arguably
maybe, perhaps, possibly, could be
How can I parse this, and insert into a database table in the format:
TABLE: Term_Glossary
================================================
Term_Name | Term_Definition |
================================================
aptitude | ability, skill, gift, talent |
------------------------------------------------
aqueous | watery |
------------------------------------------------
arguably | maybe, perhaps, possibly, could be|
================================================
Any help would be appreciated - thanks.
Update
I realize the database structure is simple/inefficient - but really, the point of my question is the code to parse the kind of text found in the first example, using C#. Thanks.
It may seem more complex at first, but you'll find it a lot easier in the long-term to think in terms of two tables:
===========================================
Term_ID | Term_Name |
===========================================
1 | aptitude |
2 | aqueous |
3 | arguably |
===========================================
===============================================
Definition_ID | Term_ID | Definition_Name |
===============================================
1 | 1 | ability |
2 | 1 | skill |
3 | 1 | gift |
4 | 1 | talent |
5 | 2 | watery |
6 | 3 | maybe |
7 | etc.etc.etc
Perhaps even think if you can normalise this further by having one table of words with IDs and a table of associations.
It looks to me like you would read the first line, save it to a variable, read the second line, save it to a second variable, then insert into the table where Term_Name = first variable, and Term_Definition = second variable.
So your logic would be like:
StreamReader SR;
string Term_Name;
string Term_Definition
SR = File.OpenText(filename);
Term_Name = SR.ReadLine();
while(Term_Name != null)
{
Term_Definition = SR.ReadLine();
// make your database call here to insert with these two variables. I don't know what DB you are using.
Term_Name = SR.ReadLine();
}
SR.Close();

Categories

Resources