Foreach inside Foreach C# - c#-4.0

Saving the value the foreach inside foreach but the inner foreach will base on the outer foreach.
All i want is to save the two data but the inner foreach will base the value of Model2.SRL of outer foreach.
string[] _stpr = {"\r\n"};
string[] _slr = Model1.SRL.Split(_stpr, RemoveEmptyEntities);
string[] _chs = Model1.CHS.Split(_stpr, RemoveEmptyEntities);
foreach(string _s in _slr)
{
Model2.SRL = _s; // Test Value : SRL-1 // TotalCount = 5
Model2.DTL = "Detail";
Model2.CHS = string.empty;
functionToSave(ref transaction);
foreach(string _c in _chs)
{
Model2.SRL = _s; // will base on value from outer loop
Model2.CHS = _c; // Test Value : CHS-1
functionToSave(ref transaction);
}
}
commit();
When executing this, the result is that the last value of inner foreach will all column in the DB if multiple items.
Output Result:
SRL = SRL-1, CHS = CHS-1,
SRL = SRL-2, CHS = CHS-1,
SRL = SRL-3, CHS = CHS-1,
SRL = SRL-4, CHS = CHS-1,
SRL = SRL-5, CHS = CHS-1,
Expected Result:
SRL = SRL-1, CHS = CHS-1
SRL = SRL-2, CHS = CHS-2
SRL = SRL-3, CHS = CHS-3
SRL = SRL-4, CHS = CHS-4
SRL = SRL-5, CHS = CHS-5

You're focussing very much on mechanism rather than relying on the framework to do the drudgery for you.
This looks like a good use case for Zip. Assuming you have a using System.Linq; directive above this code:
string[] _stpr = {"\r\n"};
string[] _slr = Model1.SRL.Split(_stpr, RemoveEmptyEntities);
string[] _chs = Model1.CHS.Split(_stpr, RemoveEmptyEntities);
int _counter = 0;
foreach(var _s in _slr.Zip(_chs, (first,second) => new { first, second })
{
Model2.SRL = _s.first;
Model2.DTL = "Detail";
Model2.CHS = _s.second;
}
commit();
You may be able to improve this further. E.g. you seem to have a single Model2 instance that's reused each time through the loop. I'd have expected something like:
_slr.Zip(_chs, (first,second) => new WhateverModel2Is
{ SRL = first, CHS = second, DTL = "Detail" })
And be working with those instances each time through the loop.

Found the answer. I just added the incremental counter per row since it was an Array.
string[] _stpr = {"\r\n"};
string[] _slr = Model1.SRL.Split(_stpr, RemoveEmptyEntities);
string[] _chs = Model1.CHS.Split(_stpr, RemoveEmptyEntities);
int _counter = 0;
foreach(string _s in _slr)
{
Model2.SRL = _s; // Test Value : SRL-1 // TotalCount = 5
Model2.DTL = "Detail";
Model2.CHS = _chs[_counter];
_counter++;
}
commit();

Related

Add dimension between link and element

i am tried to find the link wall face,but when i use the reference to create a new dimension , i will get result about 'invaild number of references'. i cant trans link face to active face.
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
var rf1 = uidoc.Selection.PickObject(ObjectType.PointOnElement, "select");
var element1 = doc.GetElement(rf1);
var location = element1.Location as LocationPoint;
var point = location.Point;
var rf2 = uidoc.Selection.PickObject(ObjectType.LinkedElement, "select");
var linkElement = doc.GetElement(rf2) as RevitLinkInstance;
var linkDoc = linkElement.GetLinkDocument();
var linkWall = linkDoc.GetElement(rf2.LinkedElementId) as Wall;
var wallLocation = linkWall.Location as LocationCurve;
var curve = wallLocation.Curve;
var cRf = curve.Reference;
var solid = BIMTools.Geometry.GetSolid(linkWall);
Face face = null;
foreach (var solidFace in solid.Faces)
{
XYZ normal = ((Face)solidFace).ComputeNormal(new UV(0, 0));
if (normal.Y < 0)
{
face = solidFace as Face;
break;
}
}
var viewLevel = uidoc.ActiveView.GenLevel.Elevation;
var tPoint = new XYZ(point.X,(face as PlanarFace).Origin.Y, viewLevel);
point = new XYZ(point.X, point.Y, viewLevel);
var line = Line.CreateBound(point, tPoint);
var references = new ReferenceArray();
references.Append(rf1);
references.Append(face.Reference);
using (Transaction trans = new Transaction(doc,"create"))
{
trans.Start();
var dimension = doc.Create.NewDimension(uidoc.ActiveView, line, references);
trans.Commit();
}
return Result.Succeeded;
}
The Building Coder provides a whole list of articles on creating dimensioning.

How to get schedule element data in revit using C#

I am new to Revit API and am working in C#. I want to get the schedule element parameters value using C#. I used the below code to get the view schedule.
var viewSchedule = new FilteredElementCollector(document)
.OfClass(typeof(ViewSchedule))
.FirstOrDefault(e => e.Name == "MyScheduleName") as ViewSchedule;
Schedule Element Data
From the above schedule, I used the below code to get the element data (please refer the above screenshot link) but it taking long time to reflect the output (10 to 15 seconds).
var rowCount = viewSchedule.GetTableData().GetSectionData(SectionType.Body).NumberOfRows;
var colCount = viewSchedule.GetTableData().GetSectionData(SectionType.Body).NumberOfColumns;
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
data += viewSchedule.GetCellText(SectionType.Body, i, j);
}
}
Please let me know is there any alternate approach to get the schedule data using C#.
Thanks in advance.
Maybe you can also use ViewSchedule.Export as demonstrated by The Building Coder discussing The Schedule API and Access to Schedule Data.
Yes, you can easily access Schedule data without exporting.
Firstly, get all the schedules and read the data cell by cell. Secondly, create dictionary and store data in form of key, value pairs. Now you can use the schedule data as you want. I have tried this in Revit 2019.
Here is the implementation.
public void getScheduleData(Document doc)
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
IList<Element> collection = collector.OfClass(typeof(ViewSchedule)).ToElements();
String prompt = "ScheduleData :";
prompt += Environment.NewLine;
foreach (Element e in collection)
{
ViewSchedule viewSchedule = e as ViewSchedule;
TableData table = viewSchedule.GetTableData();
TableSectionData section = table.GetSectionData(SectionType.Body);
int nRows = section.NumberOfRows;
int nColumns = section.NumberOfColumns;
if (nRows > 1)
{
//valueData.Add(viewSchedule.Name);
List<List<string>> scheduleData = new List<List<string>>();
for (int i = 0; i < nRows; i++)
{
List<string> rowData = new List<string>();
for (int j = 0; j < nColumns; j++)
{
rowData.Add(viewSchedule.GetCellText(SectionType.Body, i, j));
}
scheduleData.Add(rowData);
}
List<string> columnData = scheduleData[0];
scheduleData.RemoveAt(0);
DataMapping(columnData, scheduleData);
}
}
}
public static void DataMapping(List<string> keyData, List<List<string>>valueData)
{
List<Dictionary<string, string>> items= new List<Dictionary<string, string>>();
string prompt = "Key/Value";
prompt += Environment.NewLine;
foreach (List<string> list in valueData)
{
for (int key=0, value =0 ; key< keyData.Count && value< list.Count; key++,value++)
{
Dictionary<string, string> newItem = new Dictionary<string, string>();
string k = keyData[key];
string v = list[value];
newItem.Add(k, v);
items.Add(newItem);
}
}
foreach (Dictionary<string, string> item in items)
{
foreach (KeyValuePair<string, string> kvp in item)
{
prompt += "Key: " + kvp.Key + ",Value: " + kvp.Value;
prompt += Environment.NewLine;
}
}
Autodesk.Revit.UI.TaskDialog.Show("Revit", prompt);
}

How to make parent child relationship in C1flexgrid

I am using C1Flexgrid and I need to make parent child relation in this grid. But child details need to show in same grid (no other grid ) and when I clicked on + expand should happen and vice versa.
I have written below code where I am having one column in datatable related to parent and child . If it is parent then I am making it 1 else 0.
When I tried with this code. R2 row is coming as child node of r which should not be a case as it is parent node.
Please help me on this .
private void Form3_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable("customers");
dt.Columns.Add("abc");
dt.Columns.Add("ddd");
dt.Columns.Add("eee");
dt.Columns.Add("parent");
var r = dt.NewRow();
r["abc"] = "11";
r["ddd"] = "12";
r["eee"] = "13";
r["parent"] = "1";
var r1 = dt.NewRow();
r1["ddd"] = "12";
r1["eee"] = "14";
r1["parent"] = "0";
var r2 = dt.NewRow();
r2["abc"] = "11";
r2["ddd"] = "1222";
r2["eee"] = "14";
r2["parent"] = "1";
var rr32 = dt.NewRow();
rr32["abc"] = "11";
rr32["ddd"] = "1222";
rr32["eee"] = "14";
rr32["parent"] = "0";
dt.Rows.Add(r);
dt.Rows.Add(r1);
dt.Rows.Add(r2);
dt.Rows.Add(rr32);
grid1.DataSource = dt;
GroupBy("parent", 1);
// show outline tree
grid1.Tree.Column = 2;
// autosize to accommodate tree
grid1.AutoSizeCol(grid1.Tree.Column);
grid1.Tree.Show(1);
}
void GroupBy(string columnName, int level)
{
object current = null;
for (int r = grid1.Rows.Fixed; r < grid1.Rows.Count; r++)
{
if (!grid1.Rows[r].IsNode)
{
var value = grid1[r, columnName];
string value2 = grid1[r, "parent"].ToString();
if (!object.Equals(value, current))
{
// value changed: insert node, apply style
if (value2.Equals("0"))
{
grid1.Rows.InsertNode(r, level);
grid1.Rows[r].Style = _nodeStyle[Math.Min(level, _nodeStyle.Length - 1)];
r++;
}
// show group name in first scrollable column
//grid1[r, grid1.Cols.Fixed+1] = value;
// update current value
current = value;
}
}
}
}
}
Your code was almost there, i have manipulated GroupBy method to fit your need. It solves your current requirement but you have to handle sorting and other functionalists of grid yourself.
Hope this helps!
void GroupBy(string columnName, int level)
{
object current = null;
for (int r = grid1.Rows.Fixed; r < grid1.Rows.Count; r++)
{
if (!grid1.Rows[r].IsNode)
{
var value = grid1[r, columnName];
if (!object.Equals(value, current))
{
// value changed: insert node, apply style
grid1.Rows.InsertNode(r, level);
grid1.Rows[r].Style = _nodeStyle[Math.Min(level, _nodeStyle.Length - 1)];
// show group name in first scrollable column
Row row = grid1.Rows[r + 1];
for (int i = 0; i < grid1.Cols.Count; i++)
{
grid1[r, i] = row[i];
}
grid1.Rows[r + 1].Visible = false;
r++;
// update current value
current = value;
}
}
}
}

Drupal removing a node reference from a node

Ok, trying to process a script, both PHP and JavaScript, where I am moving a particular content type NODE from one reference to another. This is the structure:
I have a PROJECT
Inside each PROJECT are PAGES
Inside each PAGE are CALLOUTS
and Inside each CALLOUT are PRODUCTS.
What I want to do is take a PRODUCT from one CALLOUT to another CALLOUT. I am able to merge these, but now what I want to do is delete the first instance. An example:
I have PRODUCT AAG-794200 that is on PAGE 6 CALLOUT A. I am merging that PRODUCT with PAGE 6 CALLOUT B.
I can get the product to merge, but now I need to remove it from CALLOUT A. Here is my code:
$merge = explode(',', $merge); //Merge SKUs
$mpages = explode(',', $mpages); //Merge Pages
$mcallouts = explode(',', $mcallouts); //Merge Callouts
$mcallout_nid = explode(',', $mcallout_nid); //Merge Current callout
$length = count($merge);
$e = 0;
while ($e < $length) {
//Where is the SKU going to?
$to_callout_letter = strtoupper($mcallouts[$e]);
$to_page_num = $mpages[$e];
$sku = $merge[$e];
$from_callout = $mcallout_nid[$e];
//Where is the SKU coming from?
$other_callout = node_load($from_callout);
//Need page ID of current callout for project purposes
$page_nid = $other_callout->field_page[0]['nid'];
$page = node_load($page_nid);
//Need the project NID
$project_nid = $page->field_project[0]['nid'];
//We need to get the NID of the page we are going to
$page_nid = db_query('SELECT * FROM content_type_page WHERE field_page_order_value = "%d" and field_project_nid = "%d" ORDER BY vid DESC LIMIT 1', $to_page_num, $project_nid);
$page_nid_res = db_fetch_array($page_nid);
$to_page_nid = $page_nid_res['nid'];
//We need to get the NID of the callout here
$co_nid = db_query('SELECT * FROM content_type_callout WHERE field_identifier_value = "%s" and field_page_nid = "%d"', $to_callout_letter, $to_page_nid);
$co_nid_res = db_fetch_array($co_nid);
$to_callout_letter_nid = $co_nid_res['nid'];
//Load the present callout the SKU resides on
$f_callout = node_load($from_callout);
$callout = node_load($to_callout_letter_nid);
$long = count($f_callout->field_skus);
$deletecallout = array();
foreach($f_callout->field_skus as $skus) {
$s = 0;
while ($s < $long) {
if($skus['nid'] == $sku) {
$callout->field_skus[] = $skus;
$s++;
}
else {
$deletecallout[] = $skus;
$s++;
}
}
}
foreach($other_callout->field_images as $old_image) {
$callout->field_images[] = $old_image;
}
foreach($other_callout->field_line_art as $old_image) {
$callout->field_line_art[] = $old_image;
}
foreach($other_callout->field_swatches as $old_image) {
$callout->field_swatches[] = $old_image;
}
$callout->field_copy_text[0]['value'] .= $other_callout->field_copy_text[0]['value'];
$callout->field_notes[0]['value'] .= $other_callout->field_notes[0]['value'];
$callout->field_image_notes[0]['value'] .= $other_callout->field_image_notes[0]['value'];
$callout->field_status[0]['value'] = 'In Process';
node_save($callout);
This causes the PRODUCTS to MERGE, but not delete the original.
Thanks for any help. I know it's something simple, and it will be a palm-to-face moment.
I was actually able to solve this myself. #Chris - The brace ended after node_save(callout); I must have missed that when I copied and pasted. However, here is the code I ended up using:
$merge = explode(',', $merge); //Merge SKUs
$mpages = explode(',', $mpages); //Merge Pages
$mcallouts = explode(',', $mcallouts); //Merge Callouts
$mcallout_nid = explode(',', $mcallout_nid); //Merge Current callout
if($merge[0] !== '0') {
//Store NIDs of Old Callouts to the proper SKU
$oc_sku = array();
$oc_sku_e = count($merge);
$oc_sku_ee = 0;
while ($oc_sku_ee < $oc_sku_e) {
$curr_sku = $merge[$oc_sku_ee];
$curr_oldco = $mcallout_nid[$oc_sku_ee];
$oc_sku[$curr_sku] = $curr_oldco;
$oc_sku_ee++;
}
//Convert page numbers to page_nids
$pc = count($mpages); //How many pages are we getting
$pc_e = 0;
while($pc_e < $pc) {
$nid = $mpages[$pc_e];
$sql = db_query('SELECT * FROM content_type_page WHERE field_page_order_value = "%d" AND field_project_nid = "%d" ORDER BY vid DESC LIMIT 1', $nid, $project_nid);
$res = db_fetch_array($sql);
if($res) {
$npage_arr[] = $res['nid'];
} else { //If there is no page, we need to create it here.
$node = new StdClass();
$node->type = 'page';
$node->title = 'Page ' . $nid . ' of ' . $project->title;
$node->field_project[0]['nid'] = $project_nid;
$node->field_page_order[0]['value'] = $nid;
$node = node_submit($node);
node_save($node);
$npage_arr[] = $node->nid;
}
$pc_e++;
}
// Convert callout letters to callout_nids
$coc = count($mcallouts);
$coc_e = 0;
while($coc_e < $coc) {
$cnid = strtoupper($mcallouts[$coc_e]);
$pnid = $npage_arr[$coc_e];
$page_node = node_load($pnid);
$sql = db_query('SELECT * FROM content_type_callout WHERE field_identifier_value = "%s" AND field_page_nid = "%d" ORDER BY vid DESC LIMIT 1', $cnid, $pnid);
$res = db_fetch_array($sql);
if($res) {
$cpage_arr[] = $res['nid'];
} else { //If there is no callout that exists, we need to make it here.
$callout_node = new stdClass();
$callout_node->type = 'callout';
$callout_node->field_page[0]['nid'] = $pnid;
$callout_node->field_identifier[0]['value'] = $cnid;
$callout_node->field_sequence[0]['value'] = 0;
$callout_node->title = "Callout ".$callout." on page ".$page_node->field_page_order[0]['value'];
$callout_node->field_project[0]['nid'] = $project->nid;
$callout_node->field_wholesaler[0]['value'] = $project->field_wholesaler[0]['value'];
$callout_node->field_skus = array();
$callout_node->status = 1;
$callout_node->uid = 1;
$callout_node->revision = true;
$callout_node = node_submit($callout_node);
node_save($callout_node);
$cpage_arr[] = $callout_node->nid;
}
$coc_e++;
}
//Now we need to assign the skus to the appropriate callout for processing
$coc2 = count($cpage_arr);
$coc_e2 = 0;
while($coc_e2 < $coc2) {
$co = $cpage_arr[$coc_e2];
if($co !== '0') {
$sku = $merge[$coc_e2];
$m_arr[$co][] = $sku;
}
$coc_e2++;
}
//we need a way to centrally store all NID's of SKUs to the callouts they belong to
$oc_arr = array();
$oc = count($mcallout_nid);
$oc_e = 0;
while($oc_e < $oc) {
$f_callout = $mcallout_nid[$oc_e];
$former_callout = node_load($f_callout);
foreach($former_callout->field_skus as $key=>$skus) {
$oc_arr[] = $skus;
}
$oc_e++;
}
//Now we are processing the Pages/Callouts/SKUs to save
$pc_e2 = 0;
foreach($m_arr as $key=>$values) {
$callout = node_load($key);
foreach($values as $value) {
$oc = count($oc_arr);
$oc_e = 0;
while($oc_e < $oc) {
$skus = $oc_arr[$oc_e];
if($value == $skus['nid']) {
$callout->field_skus[] = $skus;
//$nid = $oc_sku[$value];
$old_callout_info[] = $oc_sku[$value];
$oc_e = $oc;
}
else {
$oc_e++;
}
}
}
foreach($old_callout_info as $nid) {
/* $nid = $oc_sku[$value]; */
$former_callout = node_load($nid);
foreach($former_callout->field_images as $old_image) {
$callout->field_images[] = $old_image;
}
foreach($former_callout->field_line_art as $old_image) {
$callout->field_line_art[] = $old_image;
}
foreach($former_callout->field_swatches as $old_image) {
$callout->field_swatches[] = $old_image;
}
$callout->field_copy_text[0]['value'] .= $former_callout->field_copy_text[0]['value'];
}
$callout->field_notes[0]['value'] .= $former_callout->field_notes[0]['value'];
$callout->field_image_notes[0]['value'] .= $former_callout->field_image_notes[0]['value'];
$callout->field_logos = $former_callout->field_logos;
$callout->field_affiliations = $former_callout->field_affiliations;
$callout->field_graphics = $former_callout->field_graphics;
$callout->revision = 1;
$callout->field_status[0]['value'] = 'inprocess';
node_save($callout);
$pc_e2++;
}
}
I realize this can probably be simplified in a way, but as for now, this works perfectly considering what I'm trying to do. No complaints from the client so far. Thanks for taking a look Drupal Community.

How to add a term to TermCollection (taxonomy field)

In sharePoint 2010, I want to set taxonomy values of a document field. The field can take multiple taxonomy terms.
I am doing it the wrong way because the cast of taxoTerms.Concat(terms) in TermCollection class fails :
TaxonomyField taxoField = file.Item.Fields.GetFieldByInternalName(entry.Key)
as TaxonomyField;
TaxonomySession taxoSession = new TaxonomySession(web.Site);
TermStore store = taxoSession.TermStores[taxoField.SspId];
TermSet termSet = store.GetTermSet(taxoField.TermSetId);
if (taxoField.AllowMultipleValues)
{
string[] taxoValues = entry.Value.Split(';');
TermCollection taxoTerms = termSet.GetTerms(taxoValues[0], true);
for (int j = 1; j < taxoValues.Length; j++)
{
TermCollection terms = termSet.GetTerms(taxoValues[j], true);
if (terms.Count > 0)
{
taxoTerms = (TermCollection)taxoTerms.Concat(terms);
}
}
taxoField.SetFieldValue(file.Item, taxoTerms);
}
Do you know how can I add terms to my TermCollection object so I can save the term values in the field ?
I found my solution. Here it is :
TaxonomyField taxoField =
file.Item.Fields.GetFieldByInternalName(entry.Key) as TaxonomyField;
TaxonomySession taxoSession = new TaxonomySession(web.Site);
TermStore store = taxoSession.TermStores[taxoField.SspId];
TermSet termSet = store.GetTermSet(taxoField.TermSetId);
if (taxoField.AllowMultipleValues)
{
string[] taxoValues = entry.Value.Split(';');
TermCollection terms = termSet.GetAllTerms();
List<string> taxonomyValueList = taxoValues.ToList<string>();
TaxonomyFieldValueCollection fieldValues = new TaxonomyFieldValueCollection(taxoField);
foreach (Term term in terms)
{
if (taxonomyValueList.Contains(term.Name))
{
TaxonomyFieldValue fieldValue = new TaxonomyFieldValue(taxoField);
fieldValue.TermGuid = term.Id.ToString();
fieldValue.Label = term.Name;
fieldValues.Add(fieldValue);
}
}
taxoField.SetFieldValue(file.Item, fieldValues);
}
Hope it helps others.
Here is a sample that could work:
var item = file.Item;
var taxonomyField = item.Fields.GetFieldByInternalName(entry.Key);
var values = new TaxonomyFieldValueCollection(taxonomyField);
values.PopulateFromLabelGuidPairs(entry.Value);
item[entry.Key] = values;
item.Update();
I did not test it on a life system so there can be some additional work, but I hope you get the general idea. The values in the entry.Value string have to contain the | and ; separated list of tags. If the tag does not exist you have to create it and get its id before you save it to the item.
HTH
Vojta

Resources