/// <summary> /// Get sortby by looking for the topic label and content label in the qnum survey and using that qnum /// if the content label isnt there, use the qnum for the last instance of the topic label, adding !00 to it /// if neither are there, use z /// </summary> /// <param name="topic"></param> /// <param name="content"></param> /// <param name="qnumSurvey"></param> /// <returns>string. The first Qnum that contains the provided Topic and Content labels</returns> private string GetFirstQnum(string topic, string content, ReportSurvey qnumSurvey) { string firstQnum; List <SurveyQuestion> foundQs; foundQs = qnumSurvey.Questions.Where(x => x.VarName.Topic.LabelText.Equals(topic) && x.VarName.Content.LabelText.Equals(content)).ToList(); if (foundQs.Count != 0) { firstQnum = foundQs[0].Qnum; } else { foundQs = qnumSurvey.Questions.Where(x => x.VarName.Topic.LabelText.Equals(topic)).ToList(); if (foundQs.Count != 0) { firstQnum = foundQs[0].Qnum + "!00"; } else { firstQnum = "z"; } } return(firstQnum); }
/// <summary> /// /// </summary> /// <param name="sq">The deleted question.</param> /// <param name="refSurvey">The survey that contains the deleted question.</param> public void RenumberDeletion(SurveyQuestion sq, ReportSurvey refSurvey, ReportSurvey otherSurvey) { // we need to find the last common varname between the 2 surveys, set the qnum of the row to that common row's qnum + the z-qnum string varname; string previousvar; string previousqnum = ""; varname = sq.VarName.RefVarName; for (int i = 0; i < refSurvey.Questions.Count; i++) { if (refSurvey.Questions[i].VarName.RefVarName.Equals(varname)) { if (i == 0) { previousqnum = "000"; } else { previousvar = refSurvey.Questions[i - 1].VarName.RefVarName; previousqnum = GetPreviousCommonVar(varname, refSurvey, otherSurvey); } break; } } sq.Qnum = previousqnum + '^' + sq.Qnum; }
public void CreateSyntax(ReportSurvey s, SyntaxFormat format) { OutputPath += "\\" + s.SurveyCode + " " + DateTime.Today.ToString("d"); // add the extension to this switch (format) { case SyntaxFormat.EpiData: CreateEpiQES(s); CreateEpiCHK(s); break; } }
private void CreateEpiCHK(ReportSurvey s) { using (StreamWriter tw = new StreamWriter(OutputPath + ".chk")) { // for each question, if it has response options, create a block containing: // VarName // LEGAL...END (if ro/nr not null) // AFTER ENTRY...END (if pstp not null) // END foreach (SurveyQuestion sq in s.Questions) { if (sq.ScriptOnly) { continue; } // varname tw.WriteLine(sq.VarName); // RANGE if (!string.IsNullOrEmpty(sq.RespOptions) || !string.IsNullOrEmpty(sq.NRCodes)) { if (!string.IsNullOrEmpty(sq.RespOptions) && !sq.VarType.Equals("numeric")) { tw.WriteLine(" Range 0 " + new string('7', sq.NumCol)); } } // LEGAL if (!string.IsNullOrEmpty(sq.RespOptions) || !string.IsNullOrEmpty(sq.NRCodes) && sq.VarType.Equals("numeric")) { tw.WriteLine(" LEGAL"); tw.WriteLine(" " + string.Join("\r\n ", sq.GetRespNumbers())); tw.WriteLine(" END"); } // AFTER ENTRY if (!string.IsNullOrEmpty(sq.PstP)) { tw.WriteLine(" AFTER ENTRY"); tw.WriteLine(GetAfterEntry(sq.VarName.FullVarName, new QuestionRouting(sq.PstP, sq.RespOptions), s.Questions.ToList())); tw.WriteLine(" END"); } // END tw.WriteLine("END"); tw.WriteLine(""); } } }
public bool HasSurvey(ReportSurvey s) { bool found = false; foreach (ReportSurvey rs in Surveys) { if (rs.SurveyCode.Equals(s.SurveyCode) && rs.Backend.Equals(s.Backend)) { found = true; } } return(found); }
public ReportSurvey GetSurvey(string code, DateTime backup) { ReportSurvey s = null; for (int i = 0; i < Surveys.Count; i++) { if (Surveys[i].SurveyCode == code && Surveys[i].Backend == backup) { s = Surveys[i]; break; } } return(s); }
// Returns the first survey object matching the specified id. public ReportSurvey GetSurvey(int id) { ReportSurvey s = null; for (int i = 0; i < Surveys.Count; i++) { if (Surveys[i].ID == id) { s = Surveys[i]; break; } } return(s); }
// Returns the first survey object matching the specified code. public ReportSurvey GetSurvey(string code) { ReportSurvey s = null; for (int i = 0; i < Surveys.Count; i++) { if (Surveys[i].SurveyCode == code) { s = Surveys[i]; break; } } return(s); }
// Returns the survey object that defines the Qnum order public ReportSurvey QnumSurvey() { ReportSurvey s = null; for (int i = 0; i < Surveys.Count; i++) { if (Surveys[i].Qnum) { s = Surveys[i]; break; } } return(s); }
// Returns the survey object that has been designated primary public ReportSurvey PrimarySurvey() { ReportSurvey s = null; for (int i = 0; i < Surveys.Count; i++) { if (Surveys[i].Primary) { s = Surveys[i]; break; } } return(s); }
/// <summary> /// Returns the VarName of the last common VarName between 2 datatables, starting from a specified VarName. /// </summary> /// <param name="varname">The starting point from which we will look back to find the first common VarName.</param> /// <returns>Returns the Qnum of the first common VarName that occurs before the specified VarName. If there are no common VarNmaes before this VarName, returns '000'.</returns> private string GetPreviousCommonVar(string varname, ReportSurvey refSurvey, ReportSurvey otherSurvey) { string previousQnum = ""; string prev = ""; string curr = ""; refSurvey.Questions.ToList().Sort((x, y) => x.Qnum.CompareTo(y.Qnum)); otherSurvey.Questions.ToList().Sort((x, y) => x.Qnum.CompareTo(y.Qnum)); for (int i = refSurvey.Questions.Count - 1; i >= 0; i--) { curr = refSurvey.Questions[i].VarName.RefVarName; // get the previous var in refSurvey if (curr.Equals(varname)) { if (i == 0) { prev = ""; break; } else { prev = refSurvey.Questions[i - 1].VarName.RefVarName; // check if it exists in otherSurvey var foundRow = otherSurvey.Questions.SingleOrDefault(x => x.VarName.RefVarName == prev); if (foundRow != null) { previousQnum = foundRow.Qnum; break; } else { varname = refSurvey.Questions[i - 1].VarName.RefVarName; } } } } if (prev.Equals("")) { previousQnum = "000"; } return(previousQnum); }
/// <summary> /// Remove a survey from the list /// </summary> /// <param name="s"></param> /// <remarks>Update the primary survey, then renumber the remaining surveys.</remarks> public void RemoveSurvey(ReportSurvey s) { Surveys.Remove(s); SetPrimary(); SetQnumSurvey(); // renumber surveys for (int i = 1; i <= Surveys.Count; i++) { Surveys[i - 1].ID = i; } //RemoveColumn(s.SurveyCode + " " + s.Backend.ToString("d")); }
// Add a Survey object to the list of surveys and set it's ID to the next available number starting with 1 public void AddSurvey(ReportSurvey s) { int newID = 1; Surveys.Add(s); SetPrimary(); SetQnumSurvey(); while (GetSurvey(newID) != null) { newID++; } s.ID = newID; //AddColumn(s.SurveyCode + " " + s.Backend.ToString("d")); }
/// <summary> /// Returns the name of the column, in the final survey table, containing the question text. /// </summary> /// <returns>Returns: string.</returns> protected string GetQuestionColumnName(ReportSurvey s) { string column = ""; column = s.SurveyCode.Replace(".", ""); if (!s.Backend.Equals(DateTime.Today)) { column += " " + s.Backend.ToString("d"); } if (s.Corrected) { column += " Corrected"; } if (s.Marked) { column += " Marked"; } return(column); }
public Comparison(ReportSurvey p, ReportSurvey o) { PrimarySurvey = p; OtherSurvey = o; SimilarWords = new string[1][]; ShowDeletedFields = true; ShowDeletedQuestions = true; ReInsertDeletions = true; IgnoreSimilarWords = true; Highlight = true; HighlightStyle = HStyle.Classic; HighlightScheme = HScheme.Sequential; HighlightNR = true; Intersection = new List <SurveyQuestion>(); PrimeOnly = new List <SurveyQuestion>(); OtherOnly = new List <SurveyQuestion>(); }
// TODO create method for getting SortBy (even for Qnum survey) /// <summary> /// Returns a DataTable containing all combinations of Topic and Content labels found in the survey list. Each question that appears under these /// combinations is displayed under it's own survey heading. The table is sorted by the Qnum from the first survey and any labels not found in that /// survey are collected at the bottom of the table. /// </summary> public DataTable CreateTCReport(BindingList <ReportSurvey> surveyList) { DataTable report = new DataTable(); DataRow newrow; string currentT; string currentC; string qs = ""; string firstQnum = ""; string otherFirstQnum = ""; List <SurveyQuestion> foundQs; ReportSurvey qnumSurvey = null; // start with a table containing all Topic/Content combinations present in the surveys report = CreateTCBaseTable(surveyList); foreach (ReportSurvey s in surveyList) { if (s.Qnum) { qnumSurvey = s; } } // for each T/C combination, add each survey's questions that match // there should be one row for each T/C combo, so we need to concatenate all questions with that combo foreach (DataRow tc in report.Rows) { currentC = (string)tc["Info"]; currentC = currentC.Substring(currentC.IndexOf("<em>") + 4, currentC.IndexOf("</em>") - currentC.IndexOf("<em>") - 4); currentT = (string)tc["Info"]; currentT = currentT.Substring(8, currentT.IndexOf("</strong>") - 8); // now for each survey, add the questions that match the topic content pair foreach (ReportSurvey s in surveyList) { foundQs = s.Questions.Where(x => x.VarName.Topic.LabelText.Equals(currentT) && x.VarName.Content.LabelText.Equals(currentC)).ToList(); foreach (SurveyQuestion sq in foundQs) { if (firstQnum.Equals("")) { firstQnum = sq.Qnum; } qs += "<strong>" + sq.Qnum + "</strong> (" + sq.VarName + ")" + "\r\n" + sq.GetQuestionText(s.StdFieldsChosen, true) + "\r\n\r\n"; } qs = Utilities.TrimString(qs, "\r\n\r\n"); tc[s.SurveyCode] = qs; if (s.Qnum) { tc["SortBy"] = firstQnum; tc["Qnum"] = firstQnum; } else { if (tc["SortBy"] == DBNull.Value || tc["SortBy"].Equals("")) { otherFirstQnum = GetFirstQnum(currentT, currentC, qnumSurvey); if (otherFirstQnum.Equals("z")) { firstQnum = otherFirstQnum + firstQnum; } else { firstQnum = otherFirstQnum; } tc["SortBy"] = firstQnum; } } qs = ""; firstQnum = ""; } tc.AcceptChanges(); } // add a row to start the section for unmatched labels (labels that do not exist in the Qnum survey) newrow = report.NewRow(); newrow["Info"] = "<strong>Unmatches Labels</strong>"; newrow["SortBy"] = "z000"; report.Rows.Add(newrow); report.AcceptChanges(); return(report); }
/// <summary> /// // TODO replace with server function /// </summary> /// <param name="s"></param> /// <param name="commentTypes"></param> /// <param name="commentDate"></param> /// <param name="commentAuthors"></param> /// <param name="commentSources"></param> public static void FillCommentsBySurvey(ReportSurvey s) { QuestionComment c; string query = "SELECT * FROM qryCommentsQues WHERE SurvID = @sid"; using (SqlDataAdapter sql = new SqlDataAdapter()) using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ISISConnectionString"].ConnectionString)) { conn.Open(); sql.SelectCommand = new SqlCommand(); sql.SelectCommand.Parameters.AddWithValue("@sid", s.SID); if (s.CommentFields != null && s.CommentFields.Count != 0) { query += " AND ("; for (int i = 0; i < s.CommentFields.Count; i++) { sql.SelectCommand.Parameters.AddWithValue("@commentTypes" + i, s.CommentFields[i]); query += " NoteType = @commentTypes" + i + " OR "; } query = Utilities.TrimString(query, " OR "); query += ")"; } if (s.CommentDate != null) { sql.SelectCommand.Parameters.AddWithValue("@commentDate", s.CommentDate.Value); query += " AND NoteDate >= @commentDate"; } if (s.CommentAuthors != null && s.CommentAuthors.Count != 0) { query += " AND ("; for (int i = 0; i < s.CommentAuthors.Count; i++) { sql.SelectCommand.Parameters.AddWithValue("@commentAuthors" + i, s.CommentAuthors[i]); query += " NoteInit = @commentAuthors" + i + " OR "; } query = Utilities.TrimString(query, " OR "); query += ")"; } if (s.CommentSources != null && s.CommentSources.Count != 0) { query += " AND ("; for (int i = 0; i < s.CommentSources.Count; i++) { sql.SelectCommand.Parameters.AddWithValue("@commentSources" + i, s.CommentSources[i]); query += " SourceName = @commentSources" + i + " OR "; } query = Utilities.TrimString(query, " OR "); query += ")"; } if (s.CommentText != null) { query += " AND "; sql.SelectCommand.Parameters.AddWithValue("@commentText", s.CommentText); query += " Notes LIKE '%' + @commentText + '%'"; } query += " ORDER BY NoteDate ASC"; sql.SelectCommand.CommandText = query; sql.SelectCommand.Connection = conn; try { using (SqlDataReader rdr = sql.SelectCommand.ExecuteReader()) { while (rdr.Read()) { c = new QuestionComment { Notes = new Note((int)rdr["ID"], (string)rdr["Notes"]), QID = (int)rdr["QID"], Survey = (string)rdr["Survey"], VarName = (string)rdr["VarName"], CID = (int)rdr["CID"], NoteDate = (DateTime)rdr["NoteDate"], NoteInit = (int)rdr["NoteInit"], Name = (string)rdr["Name"], NoteType = (string)rdr["NoteType"], ShortNoteType = (string)rdr["ShortForm"], SurvID = (int)rdr["SurvID"] }; if (!rdr.IsDBNull(rdr.GetOrdinal("SourceName"))) { c.SourceName = (string)rdr["SourceName"]; } if (!rdr.IsDBNull(rdr.GetOrdinal("Source"))) { c.Source = (string)rdr["Source"]; } s.QuestionByID((int)rdr["QID"]).Comments.Add(c); } } } catch (Exception e) { Console.Write(e.Message); return; } } }
/// <summary> /// Builds a table using the provided ReportSurvey data. /// </summary> /// <param name="s">Report survey</param> public DataTable MakeFinalTable(ReportSurvey s) { DataTable finalTable; DataRow newrow; string questionColumnName = GetQuestionColumnName(s); string varname; // (potentially) edited VarName field string questionFilter; // construct finalTable // finalTable will have fields for ID, Qnum, VarName, Question Text, and Labels by default // comments, translations, filters will be added if needed finalTable = new DataTable(); finalTable.Columns.Add("ID", Type.GetType("System.Int32")); finalTable.Columns.Add("SortBy", Type.GetType("System.String")); finalTable.Columns.Add("Qnum", Type.GetType("System.String")); finalTable.Columns.Add("AltQnum", Type.GetType("System.String")); finalTable.Columns.Add("VarName", Type.GetType("System.String")); finalTable.Columns.Add("refVarName", Type.GetType("System.String")); finalTable.Columns.Add(questionColumnName, Type.GetType("System.String")); finalTable.Columns.Add(questionColumnName + " AltQnum2", Type.GetType("System.String")); finalTable.Columns.Add(questionColumnName + " AltQnum3", Type.GetType("System.String")); finalTable.Columns.Add(questionColumnName + " VarLabel", Type.GetType("System.String")); finalTable.Columns.Add(questionColumnName + " Domain", Type.GetType("System.String")); finalTable.Columns.Add(questionColumnName + " Topic", Type.GetType("System.String")); finalTable.Columns.Add(questionColumnName + " Content", Type.GetType("System.String")); finalTable.Columns.Add(questionColumnName + " Product", Type.GetType("System.String")); finalTable.Columns.Add("CorrectedFlag", Type.GetType("System.Boolean")); finalTable.Columns.Add("TableFormat", Type.GetType("System.Boolean")); // comment column if (s.CommentFields != null && s.CommentFields.Count != 0) { finalTable.Columns.Add(questionColumnName + " Comments", Type.GetType("System.String")); } // translation column foreach (string lang in s.TransFields) { finalTable.Columns.Add(questionColumnName + " " + lang, Type.GetType("System.String")); } // filter columns if (s.FilterCol) { finalTable.Columns.Add(questionColumnName + " Filters", Type.GetType("System.String")); } // section bounds if (ShowSectionBounds) { finalTable.Columns.Add(questionColumnName + " FirstVarName", Type.GetType("System.String")); finalTable.Columns.Add(questionColumnName + " LastVarName", Type.GetType("System.String")); } // for each question, edit the fields according to the chosen options, // then add the fields to a new row in the final table. foreach (SurveyQuestion q in s.Questions) { // create a deep copy of just the wordings so that we can format them without affecting the original wordings SurveyQuestion wordings = q.DeepCopyWordings(); // insert Qnums before variable names if (QNInsertion) { s.InsertQnums(wordings, Numbering); s.InsertOddQnums(wordings, Numbering); } // insert Country codes into variable names if (CCInsertion) { s.InsertCountryCodes(wordings); } // remove long lists in response option column if (!ShowLongLists && Utilities.CountLines(q.RespOptions) >= 25) { wordings.RespOptions = "[center](Response options omitted)[/center]"; } // NRFormat if (NrFormat != ReadOutOptions.Neither && !string.IsNullOrEmpty(q.NRCodes)) { wordings.NRCodes = s.FormatNR(q.NRCodes, NrFormat); } // Semi-telephone format if (SemiTel) { q.FormatSemiTel(out string changedPreI, out string changedRespOptions); wordings.PreI = changedPreI; wordings.RespOptions = changedRespOptions; } // in-line routing if (InlineRouting && !String.IsNullOrEmpty(q.PstP)) { s.FormatRouting(wordings); } // routing format if (!wordings.VarName.FullVarName.StartsWith("Z")) { if (s.RoutingFormat == RoutingStyle.None) { wordings.PreP = ""; wordings.PstP = ""; } else if (s.RoutingFormat == RoutingStyle.Grey) { wordings.PreP = "<Font Color=#a6a6a6>" + wordings.PreP + "</Font>"; wordings.PstP = "<Font Color=#a6a6a6>" + wordings.PstP + "</Font>"; } } // subset tables if (SubsetTables) { if (SubsetTablesTranslation) { s.InsertTranslationTableTags(wordings); } else { if (q.TableFormat && q.Qnum.EndsWith("a")) { wordings.RespOptions = "[TBLROS]" + wordings.RespOptions; wordings.NRCodes += "[TBLROE]"; wordings.LitQ = "[LitQ]" + wordings.LitQ + "[/LitQ]"; } } } // edit VarName, but don't edit the SurveyQuestion's VarName field, since this would update the refVarName field as well varname = q.VarName.FullVarName; if (VarChangesCol && !string.IsNullOrEmpty(q.VarName.FullVarName) && !q.VarName.FullVarName.StartsWith("Z") && (q.PreviousNameList.Count > 0)) { varname += " (Prev. "; foreach (VariableName v in q.PreviousNameList) { varname += v.RefVarName + ", "; } varname = varname.Substring(0, varname.Length - 2) + ")"; } // corrected if (q.CorrectedFlag) { if (s.Corrected) { varname += "\r\n" + "[C]"; } else { varname += "\r\n" + "[A]"; } } // now we can add the fields to a DataRow to be inserted into the final table newrow = finalTable.NewRow(); newrow["ID"] = q.ID; newrow["SortBy"] = q.Qnum; newrow["Qnum"] = q.GetQnum(); newrow["VarName"] = varname; newrow["refVarName"] = q.VarName.RefVarName; // concatenate the question fields, and if this is varname BI104, attach the essential questions list newrow[questionColumnName] = wordings.GetQuestionText(s.StdFieldsChosen); if (q.VarName.RefVarName.Equals("BI104")) { newrow[questionColumnName] += "\r\n<strong>" + s.EssentialList + "</strong>"; } // labels (only show labels for non-headings) if (!q.VarName.FullVarName.StartsWith("Z") || !ShowQuestion) { newrow[questionColumnName + " AltQnum2"] = q.AltQnum2; newrow[questionColumnName + " AltQnum3"] = q.AltQnum3; newrow[questionColumnName + " VarLabel"] = q.VarName.VarLabel; newrow[questionColumnName + " Topic"] = q.VarName.Topic.LabelText; newrow[questionColumnName + " Content"] = q.VarName.Content.LabelText; newrow[questionColumnName + " Domain"] = q.VarName.Domain.LabelText; newrow[questionColumnName + " Product"] = q.VarName.Product.LabelText; } // comments try { foreach (QuestionComment c in q.Comments) { newrow[questionColumnName + " Comments"] += c.GetComments() + "\r\n\r\n"; } } catch { } // translations foreach (string lang in s.TransFields) { if (s.EnglishRouting) { newrow[questionColumnName + " " + lang] = wordings.GetEnglishRoutingTranslation(lang).Replace("<br>", "\r\n"); } else { newrow[questionColumnName + " " + lang] = wordings.GetTranslationText(lang).Replace("<br>", "\r\n"); } } // filters if (s.FilterCol) { newrow[questionColumnName + " Filters"] = q.Filters; } newrow["CorrectedFlag"] = q.CorrectedFlag; newrow["TableFormat"] = q.TableFormat; // section bounds if (ShowSectionBounds) { newrow[questionColumnName + " FirstVarName"] = s.GetSectionLowerBound(q); newrow[questionColumnName + " LastVarName"] = s.GetSectionUpperBound(q); } // now add a new row to the finalTable DataTable // the new row will be a susbet of columns in the rawTable, after the above modifications have been applied finalTable.Rows.Add(newrow); } // apply the question filters questionFilter = s.GetQuestionFilter(); if (!questionFilter.Equals("")) { try { finalTable = finalTable.Select(questionFilter).CopyToDataTable().Copy(); } catch (InvalidOperationException) { return(null);// filters resulted in 0 records } } // set the primary key to be the refVarName column // so that surveys from differing countries can still be matched up finalTable.PrimaryKey = new DataColumn[] { finalTable.Columns["refVarName"] }; // remove unneeded fields if (!ShowQuestion) { finalTable.Columns.Remove(questionColumnName); } // check enumeration and delete AltQnum if (Numbering == Enumeration.Qnum) { finalTable.Columns.Remove("AltQnum"); } if (Numbering == Enumeration.AltQnum) { finalTable.Columns.Remove("Qnum"); } if (!s.AltQnum2Col) { finalTable.Columns.Remove(questionColumnName + " AltQnum2"); } if (!s.AltQnum3Col) { finalTable.Columns.Remove(questionColumnName + " AltQnum3"); } if (!s.DomainLabelCol) { finalTable.Columns.Remove(questionColumnName + " Domain"); } if (!s.TopicLabelCol) { finalTable.Columns.Remove(questionColumnName + " Topic"); } if (!s.ContentLabelCol) { finalTable.Columns.Remove(questionColumnName + " Content"); } if (!s.VarLabelCol) { finalTable.Columns.Remove(questionColumnName + " VarLabel"); } if (!s.ProductLabelCol) { finalTable.Columns.Remove(questionColumnName + " Product"); } // these are no longer needed finalTable.Columns.Remove("CorrectedFlag"); finalTable.Columns.Remove("TableFormat"); finalTable.Columns.Remove("ID"); return(finalTable); }
private void CreateEpiQES(ReportSurvey s) { using (StreamWriter tw = new StreamWriter(OutputPath + ".qes")) { string qnumPre; string line; int longestVarLabel = 0; int longestLine = 0; // create a header section tw.WriteLine(s.Title); tw.WriteLine(""); // ID Code section tw.WriteLine("- ID Code -"); tw.WriteLine(""); // survey/screener section if (s.SurveyCode.EndsWith("sc")) { qnumPre = "S"; tw.WriteLine("- SCREENER SECTION -"); } else { qnumPre = "Q"; tw.WriteLine("- SURVEY SECTION -"); } // determine the longest varlabel foreach (SurveyQuestion sq in s.Questions) { if (sq.VarName.VarLabel.Length > longestVarLabel) { longestVarLabel = sq.VarName.VarLabel.Length; } } // longest possible line is: // VarName with CC and suffix (10) // 2 spaces (2) // Qnum with suffix and 'Q' (5) // space dash dash space (4) // longest varlabel in list of questions longestLine = 10 + 2 + 5 + 4 + longestVarLabel; foreach (SurveyQuestion sq in s.Questions) { if (sq.ScriptOnly) { continue; } line = "{" + sq.VarName + "} " + qnumPre + sq.Qnum + " -- " + sq.VarName.VarLabel.Replace("#", "num"); while (line.Length < longestLine) { line += " "; } switch (sq.VarType) { case "numeric": for (int i = 0; i < sq.NumCol; i++) { line += "#"; } break; case "string": for (int i = 0; i < sq.NumCol; i++) { line += "_"; } break; } tw.WriteLine(line); } } }