static void ParseListOfLink(XElement page, ITransformGroup group) { IEnumerable <XElement> links = page.Elements(XName.Get("Links")); IEnumerable <XElement> linkList = null; foreach (XElement l in links) { linkList = l.Elements(XName.Get("Link")); break; } foreach (XElement link in linkList) { ITransformLink docLink = ParseLink(link); group.Links.Add(docLink); } }
public SpecCertGenerationResult GenerateSpecCert(MapDetail mapDetail) { SpecCertGenerationResult result = new SpecCertGenerationResult(); string currentDir = Path.GetDirectoryName(Assembly.GetAssembly(typeof(SpecCertGenerator)).Location); string specCertName = string.Format("{0} - Spec Cert - XML - {1} - {2}.xlsx", mapDetail.OrgName, mapDetail.DocumentType, mapDetail.Direction.ToLower()); string specCertPath = Path.Combine(currentDir, specCertName); bool useSource = string.Equals(mapDetail.Direction, "receive", StringComparison.OrdinalIgnoreCase); string templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, TemplateFile); if (File.Exists(specCertPath)) { File.Delete(specCertPath); } using (ExcelPackage pck = new ExcelPackage(new FileInfo(templateFile))) { ExcelWorkbook workBook = pck.Workbook; ExcelWorksheet specCertWorksheet = workBook.Worksheets[1]; specCertWorksheet.Name = string.Format("{0} {1} Spec Worksheet", mapDetail.DocumentType, mapDetail.Direction.ToUpper()); Dictionary <string, ITransformLink> links = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> fromLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> toLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, IFormula> formulas = new Dictionary <string, IFormula>(); Dictionary <string, XmlLinkInfo> xmlLinks = new Dictionary <string, XmlLinkInfo>(); IReferenceableElement refElement; string rootNodeName = null; foreach (ITransformGroup transformGroup in mapDetail.Map.Facets) { foreach (ITransformLink link in transformGroup.Links) { links.Add(link.Name, link); if (link.Source != null && link.Source.ReferenceType == ReferenceType.Formula && !fromLinks.ContainsKey(link.Source.Name)) { fromLinks.Add(link.Source.Name, link); } if (link.Target != null && link.Target.ReferenceType == ReferenceType.Formula && !toLinks.ContainsKey(link.Target.Name)) { toLinks.Add(link.Target.Name, link); } refElement = useSource ? link.Source : link.Target; //Skip first part of path string path = refElement.Name.Substring(refElement.Name.IndexOf("->") + 2); if (refElement.ReferenceType == ReferenceType.Document && !xmlLinks.ContainsKey(path)) { if (rootNodeName == null) { rootNodeName = refElement.Name.Substring(0, refElement.Name.IndexOf("->")); specCertWorksheet.Cells[RootNodeNameRowIndex, RootNodeNameColumnIndex].Value = rootNodeName; } xmlLinks.Add(path, new XmlLinkInfo(link.Name)); } } foreach (IFormula formula in transformGroup.Formulas) { formulas.Add(formula.Name, formula); } } // TODO: Check done for receive only // Set IsOptional to false if formula is not of type Logical* if (useSource) { foreach (XmlLinkInfo xmlLink in xmlLinks.Values) { ITransformLink link = links[xmlLink.LinkName]; if (link.Target.ReferenceType == ReferenceType.Formula) { IFormula formula = formulas[link.Target.Name]; if (formula.FormulaType == FormulaType.LogicalString || formula.FormulaType == FormulaType.LogicalExistence) { xmlLink.IsOptional = true; } } } } result.PathsUsed = new List <string>(); int row = StartRowIndex; int mandatoryColumnIndex = useSource ? ReceiveMandatoryColumnIndex : SendMandatoryColumnIndex; string[] prevParts = null; List <string> paths = xmlLinks.Keys.ToList(); paths.Sort(); foreach (string path in paths) { XmlLinkInfo xmlLink = xmlLinks[path]; string[] parts = path.Split(new string[] { "->" }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length > 5) { throw new NotSupportedException(string.Format("More than 5 levels deep xml elements are not supported. Path: {0}", path)); } int level = 0; if (prevParts != null) { while (level < prevParts.Length && level < parts.Length && prevParts[level] == parts[level]) { level++; } } prevParts = parts; while (level < parts.Length) { bool highlightRow = level < parts.Length - 1 || xmlLinks.Count(entry => entry.Key.StartsWith(path + "->")) != 0; AddRow(specCertWorksheet, row, level + 1, parts[level], mandatoryColumnIndex, highlightRow, xmlLink.IsOptional || level < parts.Length - 1); level++; row++; } result.PathsUsed.Add(path); } // Add errors to spec cert worksheet //AddErrorsWorksheet(workBook, result); if (result.PathsUsed.Count != 0) { pck.SaveAs(new FileInfo(specCertPath)); result.SpecCertGenerated = true; } } result.SpecCertPath = specCertPath; return(result); }
public SpecCertGenerationResult GenerateSpecCert(MapDetail mapDetail) { SpecCertGenerationResult result = new SpecCertGenerationResult(); if (!mappingsAvailable) { // Not thread safe, but we don't really need it right now ReadCovastToX12Maps(); } string currentDir = Path.GetDirectoryName(Assembly.GetAssembly(typeof(SpecCertGenerator)).Location); //string currentDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase); string specCertName = string.Format("{0} - Spec Cert - 4010 - {1} - {2}.xlsx", mapDetail.OrgName, mapDetail.DocumentType, mapDetail.Direction.ToLower()); string specCertPath = Path.Combine(currentDir, specCertName); bool useSource = string.Equals(mapDetail.Direction, "receive", StringComparison.OrdinalIgnoreCase); Dictionary <string, List <string> > covastToX12Map; string templateFile = string.Empty; switch (mapDetail.DocumentType) { case 810: templateFile = TemplateFile_810; if (useSource) { covastToX12Map = Map_810_Inbound; } else { covastToX12Map = Map_810_Outbound; } break; case 850: templateFile = TemplateFile_850; if (useSource) { covastToX12Map = Map_850_Inbound; } else { covastToX12Map = Map_850_Outbound; } break; case 856: templateFile = TemplateFile_856; if (useSource) { covastToX12Map = Map_856_Inbound; } else { covastToX12Map = Map_856_Outbound; } break; default: result.Errors.Add(string.Format("Spec cert generation for document type {0} not supported", mapDetail.DocumentType)); return(result); } templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, templateFile); if (File.Exists(specCertPath)) { File.Delete(specCertPath); } //using (StreamReader streamReader = new StreamReader(templateFile)) //using (ExcelPackage pck = new ExcelPackage(streamReader.BaseStream)) using (ExcelPackage pck = new ExcelPackage(new FileInfo(templateFile))) { ExcelWorkbook workBook = pck.Workbook; ExcelWorksheet specCertWorksheet = workBook.Worksheets[1]; specCertWorksheet.Name = string.Format("{0} {1} Spec Worksheet", mapDetail.DocumentType, mapDetail.Direction.ToUpper()); Dictionary <string, ITransformLink> links = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> fromLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> toLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, IFormula> formulas = new Dictionary <string, IFormula>(); // Check if version is supported // Take any link and check source/target name IList <ITransformLink> refLinks = mapDetail.Map.Facets[0].Links; IReferenceableElement refElement = null; for (int i = 0; i < refLinks.Count; i++) { if (useSource) { refElement = mapDetail.Map.Facets[0].Links[i].Source; } else { refElement = mapDetail.Map.Facets[0].Links[i].Target; } if (refElement.ReferenceType == ReferenceType.Document) { break; } } if (refElement.Name.StartsWith("ASC_X12_810_004_010_DEFAULT_X") == false && refElement.Name.StartsWith("ASC_X12_850_004_010_DEFAULT_X") == false && refElement.Name.StartsWith("ASC_X12_856_004_010_DEFAULT_X") == false) { throw new NotSupportedException(string.Format("Invalid root (version) name {0}. Valid value is ASC_X12_810|850|856_004_010_DEFAULT_X", refElement.Name.Substring(0, refElement.Name.IndexOf("->")))); } foreach (ITransformGroup transformGroup in mapDetail.Map.Facets) { foreach (ITransformLink link in transformGroup.Links) { links.Add(link.Name, link); if (link.Source != null && link.Source.ReferenceType == ReferenceType.Formula && !fromLinks.ContainsKey(link.Source.Name)) { fromLinks.Add(link.Source.Name, link); } if (link.Target != null && link.Target.ReferenceType == ReferenceType.Formula && !toLinks.ContainsKey(link.Target.Name)) { toLinks.Add(link.Target.Name, link); } } foreach (IFormula formula in transformGroup.Formulas) { formulas.Add(formula.Name, formula); } } // Get all enum values // Enum values are determined as // Document(1) => One or more Formula (Equal) => Logical Or formula => Document(2) // allEnumValues store first Document(1), Document(2), enum values Dictionary <string, Dictionary <string, List <string> > > allEnumValues = new Dictionary <string, Dictionary <string, List <string> > >(); foreach (ITransformLink link in links.Values) { if (useSource == false) { if (link.Source.ReferenceType == ReferenceType.Document && link.Target.ReferenceType == ReferenceType.Formula) { IFormula formula = formulas[link.Target.Name]; // In case of enum formulas it's possible that scripting formula is first applied to convert enum value // If that is the case ignore scripting formula and move to next formula if (formula.Parameters != null && formula.FormulaType == FormulaType.Scripting) { ITransformLink equalLink = fromLinks[formula.Name]; if (equalLink.Target != null && equalLink.Target.ReferenceType == ReferenceType.Formula) { string equalFormulaName = equalLink.Target.Name; formula = formulas[equalFormulaName]; } } if (formula.Parameters != null && formula.FormulaType == FormulaType.Equality) { // Assumption: only 1 enum value and only 1 target formula exist string enumValue = null; foreach (IParameter parameter in formula.Parameters) { if (parameter.Reference.ReferenceType == ReferenceType.Literal) { if (enumValue != null) { throw new NotSupportedException("Multiple enum values in 1 formula"); } enumValue = parameter.Reference.Name; } } // If there are enum values check what's the target of these values if (!string.IsNullOrEmpty(enumValue)) { ITransformLink equalLink = fromLinks[formula.Name]; if (equalLink.Target != null && equalLink.Target.ReferenceType == ReferenceType.Formula) { string targetFormulaName = equalLink.Target.Name; IFormula targetFormula = formulas[targetFormulaName]; // Check if the equal link points to logical or formula, if it is then the target link of that will give us the document if (targetFormula.FormulaType == FormulaType.LogicalOr) { string targetDocumentName = null; ITransformLink logicalOrLink = fromLinks[targetFormulaName]; if (logicalOrLink.Target != null && logicalOrLink.Target.ReferenceType == ReferenceType.Document) { targetDocumentName = logicalOrLink.Target.Name; if (!string.IsNullOrEmpty(targetDocumentName)) { Dictionary <string, List <string> > nodeEnumValues; if (!allEnumValues.TryGetValue(link.Source.Name, out nodeEnumValues)) { nodeEnumValues = new Dictionary <string, List <string> >(); allEnumValues.Add(link.Source.Name, nodeEnumValues); } List <string> enumValues = null; if (!nodeEnumValues.TryGetValue(targetDocumentName, out enumValues)) { enumValues = new List <string>(); nodeEnumValues.Add(targetDocumentName, enumValues); } enumValues.Add(enumValue); } } } } } } } } } foreach (ITransformGroup transformGroup in mapDetail.Map.Facets) { foreach (ITransformLink link in transformGroup.Links) { IReferenceableElement toRefElement = link.Target; IReferenceableElement fromRefElement = link.Source; if (useSource) { toRefElement = link.Source; fromRefElement = link.Target; } if (toRefElement.ReferenceType == ReferenceType.Document) { try { x12Paths = null; // Check if source has enum values List <string> enumValues = GetEnumValues(link.Source.Name, toRefElement, allEnumValues); if (enumValues != null) { AddEnumValues(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource, enumValues); } else { if (fromRefElement.ReferenceType == ReferenceType.Formula && (formulas[fromRefElement.Name].FormulaType == FormulaType.LogicalExistence || formulas[fromRefElement.Name].FormulaType == FormulaType.LogicalString || formulas[fromRefElement.Name].FormulaType == FormulaType.GreaterThan)) { AddExistsCheckNote(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource); //SetMandatoryValue(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource, "n"); } else { // In case of looping do not set the mandatory flag for the segment if (!(fromRefElement.ReferenceType == ReferenceType.Formula && formulas[fromRefElement.Name].FormulaType == FormulaType.Looping)) { SetMandatoryValue(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource, "y"); } //else //SetMandatoryValue(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource, "n"); } } if (x12Paths != null) { result.PathsUsed.AddRange(x12Paths); } } catch (Exception ex) { result.Errors.Add(ex.Message); } } } } // Add errors to spec cert worksheet //AddErrorsWorksheet(workBook, result); if (result.PathsUsed.Count != 0) { pck.SaveAs(new FileInfo(specCertPath)); result.SpecCertGenerated = true; } } result.SpecCertPath = specCertPath; return(result); }
static void GenerateWorksheetFromFacets(ExcelWorkbook workBook, IList <ITransformGroup> facets, string sourceDocName, string targetDocName) { string name = string.Format("{0} -> {1}", sourceDocName, targetDocName); var ws = workBook.Worksheets.Add(name); ws.View.ShowGridLines = true; ws.Column(SegmentNameIndex).Width = 10; ws.Column(SourceFieldIndex).Width = 10; ws.Column(TargetFieldIndex).Width = 10; ws.Column(TypeIndex).Width = 8; ws.Column(GroupNameIndex).Width = 10; ws.Column(TargetRecordIndex).Width = 15; ws.Column(SourceRecordIndex).Width = 15; //ws.Column(NotesIndex).Width = 10; //Headers ws.Cells["A1"].Value = "Segment"; ws.Cells["B1"].Value = "Target Field"; ws.Cells["C1"].Value = "Source Field"; ws.Cells["D1"].Value = "Type"; ws.Cells["E1"].Value = "Group Name"; ws.Cells["F1"].Value = "Target Record"; ws.Cells["G1"].Value = "Source Record"; ws.Cells["A1:G1"].Style.Font.Bold = true; ws.View.FreezePanes(2, 1); ws.Select("A1"); //Start at row 2; int row = 2; foreach (ITransformGroup group in facets) { Dictionary <string, ITransformLink> referencedLinkMap; Dictionary <string, IFormula> formulaMap; GetReferencedLinksAndFormula(group, out referencedLinkMap, out formulaMap); //Pass1 //There are 2 things to be done in this pass //1. Set LinkName, Src and Target colums for Document XPath references //2. If Target contains formula, set formula.Address to TargetFieldIndex string fieldName, recordName; string prevTargetRecordName = string.Empty; int level = 0; foreach (ITransformLink link in group.Links) { if (link.Ignore) { continue; } //set the link address to the base row //All references from formula are to either the source or target of link, which can be //derived from the link base address //ws.Cells[row, LinkGroupNameIndex].Value = link.Name; if (link.Target.ReferenceType == ReferenceType.Document) { GetFieldAndRecordName(link.Target.Name, out fieldName, out recordName); /* * if (recordName != prevTargetRecordName) * { * //a new record is being encountered * //reset level to 0 and create a header row * level = 1; * ws.Cells[row, SegmentNameIndex].Value = recordName; * ws.Row(row).OutlineLevel = level; * ws.Row(row).Collapsed = true; * prevTargetRecordName = recordName; * row++; * } * * else * { * level = 2; * } */ ws.Cells[row, TargetFieldIndex].Value = fieldName; ws.Cells[row, TargetRecordIndex].Value = recordName; ws.Cells[row, TypeIndex].Value = "Data Copy"; //ws.Row(row).OutlineLevel = level; //ws.Row(row).Collapsed = true; } else if (link.Target.ReferenceType == ReferenceType.Formula) { string formulaAddress = GetCellAddress(ws, row, TargetFieldIndex); IFormula formula = formulaMap[link.Target.Name]; if (string.IsNullOrEmpty(formula.Address)) { formula.Address = formulaAddress; } //ws.Cells[row, TargetFieldIndex].Value = ToString(formula); ws.Cells[row, TargetFieldIndex].Style.Font.Bold = true; ws.Cells[row, TypeIndex].Value = "Formula"; } if (link.Source.ReferenceType == ReferenceType.Document) { GetFieldAndRecordName(link.Source.Name, out fieldName, out recordName); ws.Cells[row, SourceFieldIndex].Value = fieldName; ws.Cells[row, SourceRecordIndex].Value = recordName; ws.Cells[row, TypeIndex].Value = "Data Copy"; //ws.Row(row).OutlineLevel = level; //ws.Row(row).Collapsed = true; } else if (link.Source.ReferenceType == ReferenceType.Formula) { ws.Cells[row, SourceFieldIndex].Style.Font.Bold = true; ws.Cells[row, TypeIndex].Value = "Formula"; } link.Address = row.ToString(); ws.Cells[row, GroupNameIndex].Value = group.Name; row++; } //Pass2 //2nd pass, populate the address for links whose source contains a formula //Given that this formula is the source of value, it must have been the target //somewhere. Find that part and add it's address foreach (ITransformLink link in group.Links) { if (link.Ignore) { continue; } int rowNum = int.Parse(link.Address); if (link.Source.ReferenceType == ReferenceType.Formula) { IFormula formula = formulaMap[link.Source.Name]; if (string.IsNullOrEmpty(formula.Address)) { throw new ArgumentNullException("formula has null address"); } ws.Cells[rowNum, SourceFieldIndex].Formula = formula.Address; } } //Pass3 //Now populate the address of the parameters in each formula foreach (IFormula formula in group.Formulas) { if (formula.Ignore) { continue; } foreach (IParameter param in formula.Parameters) { if (param.Reference.ReferenceType == ReferenceType.Document) { ITransformLink link = referencedLinkMap[param.Reference.Name]; //B stands for sourceColumns. Todo: remove hardcoding and programmatically //determine the columns letter.User may have moved around columns param.Address = LinkSourceColumn + link.Address; } } //ExcelRange range = ws.Cells[formula.Address]; //range.Value = ToString(formula); } //Pass4 //Render the formula foreach (ITransformLink link in group.Links) { if (link.Ignore) { continue; } int rowNum = int.Parse(link.Address); if (link.Target.ReferenceType == ReferenceType.Formula) { IFormula formula = formulaMap[link.Target.Name]; if (string.IsNullOrEmpty(formula.Address)) { throw new ArgumentNullException("formula has null address"); } bool isFormulaRender; string expression = ToString(formula, out isFormulaRender); if (isFormulaRender) { ws.Cells[rowNum, TargetFieldIndex].Formula = expression; } else { ws.Cells[rowNum, TargetFieldIndex].Value = expression; } } } } string filterRange = string.Format(AutoFilterFormat, row.ToString()); ws.Cells[filterRange].AutoFilter = true; ws.Cells[1, 1, row, 7].AutoFitColumns(); }
private const string DefaultSegmentDelimiter = "13 10"; // \r\n public SpecCertGenerationResult GenerateSpecCert(MapDetail mapDetail) { SpecCertGenerationResult result = new SpecCertGenerationResult(); string currentDir = Path.GetDirectoryName(Assembly.GetAssembly(typeof(SpecCertGenerator)).Location); string specCertName = string.Format("{0} - Spec Cert - Flat File - {1} - {2}.xlsx", mapDetail.OrgName, mapDetail.DocumentType, mapDetail.Direction.ToLower()); string specCertPath = Path.Combine(currentDir, specCertName); bool useSource = string.Equals(mapDetail.Direction, "receive", StringComparison.OrdinalIgnoreCase); string templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, TemplateFile); if (File.Exists(specCertPath)) { File.Delete(specCertPath); } using (ExcelPackage pck = new ExcelPackage(new FileInfo(templateFile))) { ExcelWorkbook workBook = pck.Workbook; ExcelWorksheet specCertWorksheet = workBook.Worksheets[1]; specCertWorksheet.Name = string.Format("{0} {1} Spec Worksheet", mapDetail.DocumentType, mapDetail.Direction.ToUpper()); Dictionary <string, ITransformLink> links = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> fromLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> toLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, IFormula> formulas = new Dictionary <string, IFormula>(); Dictionary <string, LinkInfo> xmlLinks = new Dictionary <string, LinkInfo>(); IReferenceableElement refElement; string rootNodeName = null; specCertWorksheet.Cells[ElementDelimiterRowIndex, ElementDelimiterColumnIndex].Value = DefaultElementDelimiter; specCertWorksheet.Cells[SegmentDelimiterRowIndex, SegmentDelimiterColumnIndex].Value = DefaultSegmentDelimiter; foreach (ITransformGroup transformGroup in mapDetail.Map.Facets) { foreach (ITransformLink link in transformGroup.Links) { links.Add(link.Name, link); if (link.Source != null && link.Source.ReferenceType == ReferenceType.Formula && !fromLinks.ContainsKey(link.Source.Name)) { fromLinks.Add(link.Source.Name, link); } if (link.Target != null && link.Target.ReferenceType == ReferenceType.Formula && !toLinks.ContainsKey(link.Target.Name)) { toLinks.Add(link.Target.Name, link); } refElement = useSource ? link.Source : link.Target; if (refElement.Name.Contains("->") == false) { continue; } //Skip first part of path string path = refElement.Name.Substring(refElement.Name.IndexOf("->") + 2); if (refElement.ReferenceType == ReferenceType.Document && !xmlLinks.ContainsKey(path)) { xmlLinks.Add(path, new LinkInfo(link.Name)); } } foreach (IFormula formula in transformGroup.Formulas) { formulas.Add(formula.Name, formula); } } // TODO: Check done for receive only // Set IsOptional to false if formula is not of type Logical* if (useSource) { foreach (LinkInfo xmlLink in xmlLinks.Values) { ITransformLink link = links[xmlLink.LinkName]; if (link.Target.ReferenceType == ReferenceType.Formula) { IFormula formula = formulas[link.Target.Name]; if (formula.FormulaType == FormulaType.LogicalString || formula.FormulaType == FormulaType.LogicalExistence) { xmlLink.IsOptional = true; } } } } result.PathsUsed = new List <string>(); int row = StartRowIndex; int mandatoryColumnIndex = useSource ? ReceiveMandatoryColumnIndex : SendMandatoryColumnIndex; List <string> paths = xmlLinks.Keys.ToList(); paths.Sort(); string lastIterationSegmentName = null; foreach (string path in paths) { LinkInfo link = xmlLinks[path]; string[] partsTemp = path.Split(new string[] { "->" }, StringSplitOptions.RemoveEmptyEntries); List <string> parts = partsTemp.ToList(); parts.Remove("Loop"); // Only loop name is ignored as loop name is added on the segment row if (parts.Count <= 1) { continue; } if (parts.Count > 3) { throw new NotSupportedException(string.Format("More than 5 levels deep xml elements are not supported. Path: {0}", path)); } string loopName = parts[0].Contains("Loop") ? parts[0] : string.Empty; // Loop name is optional string segmentName = string.IsNullOrEmpty(loopName) ? parts[0] : parts[1]; // Some maps may have mapping only for segments (e.g. Header, BodyLoop etc.) that means // data element is optional string dataElementName = null; int index = 2; if (string.IsNullOrEmpty(loopName)) { index = 1; } if (parts.Count > index) { dataElementName = parts[index]; } // If segment changed then add segment row if (segmentName.Equals(lastIterationSegmentName, StringComparison.OrdinalIgnoreCase) == false) { AddSegmentRow(specCertWorksheet, row, loopName, segmentName, mandatoryColumnIndex, link.IsOptional || !string.IsNullOrEmpty(dataElementName)); lastIterationSegmentName = segmentName; row++; } if (string.IsNullOrEmpty(dataElementName) == false) { AddDataElementRow(specCertWorksheet, row, dataElementName, mandatoryColumnIndex, link.IsOptional); row++; } result.PathsUsed.Add(path); } // Add errors to spec cert worksheet //AddErrorsWorksheet(workBook, result); if (result.PathsUsed.Count != 0) { pck.SaveAs(new FileInfo(specCertPath)); result.SpecCertGenerated = true; } } result.SpecCertPath = specCertPath; return(result); }