}//end RowToCSVLine
		public string RowToCSVLine(int AtInternalRowIndex, bool bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty, int ColumnStart, int ColumnCount) {
			int iAbs=ColumnStart;
			string sReturn="";
			try {
				for (int ColRel=0; ColRel<ColumnCount&&iAbs<this.Columns; ColRel++) {
					sReturn+=((ColRel!=0)?",":"")+RTable.LiteralFieldToCSVField(tearr[AtInternalRowIndex].Field(iAbs),this.cFieldDelimiter,this.cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty);
					iAbs++;
				}
			}
			catch (Exception exn) {
				RReporting.ShowExn(exn,"converting row to csv line","rtable RowToCSVLine(AtInternalRowIndex="+AtInternalRowIndex+",bTabsAsNewLines="+(bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty?"true":"false")+",ColumnStart="+ColumnStart+",ColumnCount="+ColumnCount+")");
			}
			return sReturn;
		}
		public string TitlesToCSVLine(bool bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty, bool bExtendedTitleColumns, int ColumnStart, int ColumnCount) {
			string sReturn="";
			RecheckIntegrity();
			if (this.teTitles!=null) {
				if (bExtendedTitleColumns) {
					string sField="";
					int ColAbs=ColumnStart;
					for (int ColRel=0; ColRel<ColumnCount; ColRel++) {
						sField="";
						if (bExtendedTitleColumns) {
							sField=RString.SafeString(GetForcedType(ColAbs),false);
							if (sField!="") sField+=" ";
						}//end if bExtendedTitleColumns
						string FieldDataNow=teTitles.Field(ColAbs);
						if (FieldDataNow==null) {
							RReporting.ShowErr("Can't access field","generating csv line","TitlesToCSVLine {NewLineInField:"+(bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty?"TAB":"BR with marker")+"; Row:title; Column:"+ColAbs+"}");
						}
						sField+=RString.SafeString(FieldDataNow,false);
						if (bExtendedTitleColumns) {
							string sMeta=GetForcedMeta(ColAbs);
							if (sMeta!=null) {
								sMeta=RString.SafeString(sMeta,false);
								sMeta=RString.RemoveEndsWhiteSpace(sMeta);
								if (!sMeta.StartsWith("{")) {
									sMeta=RString.Replace(sMeta,"{","");
									sMeta="{"+sMeta;
								}
								if (!sMeta.EndsWith("}")) {
									sMeta=RString.Replace(sMeta,"}","");
									sMeta+="}";
								}
								sField+=sMeta;
							}//end if metadata
						}//end if bExtendedTitleColumns
						sReturn+=((ColRel!=0)?",":"")+RTable.LiteralFieldToCSVField(sField,this.cFieldDelimiter,this.cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty);
						ColAbs++;
					}//end for field (column header)
				}
				else sReturn=teTitles.ToCSVLine(cFieldDelimiter, cTextDelimiter, bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty,ColumnStart,ColumnCount);
			}
			else RReporting.ShowErr("Cannot read nonexistant title row.","Converting table titles to text line","TitlesToCSVLine");
			return sReturn;
		}
		}//end Save
		public bool SaveChunk(string sFile, bool bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty, bool bExtendedTitleColumns, int RowStart, int RowCount, int ColStart, int ColCount) {
			StreamWriter fsDest=null;
			//sLastFile=sFile; do NOT set, since only saving a chunk and therefore says nothing about the source
			//if (sLastFile==null) sLastFile="";
			bool bGood=false;
			//int iLines=0;
			RecheckIntegrity();
			try {
				fsDest=new StreamWriter(sFile);
				if (TitleRowIsNonBlank) {
					//fsDest.WriteLine(teTitles.ToCSVLine(cFieldDelimiter,cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty));
					string sTitles="";
					string sField="";
					int ColAbs=ColStart;
					for (int ColRel=0; ColRel<ColCount; ColRel++) {
						sField="";
						if (bExtendedTitleColumns) {
							sField=RString.SafeString(GetForcedType(ColAbs),false);
							if (sField!="") sField+=" ";
						}//end if bExtendedTitleColumns
						string FieldDataNow=teTitles.Field(ColAbs);
						if (FieldDataNow==null) {
							RReporting.ShowErr("Can't access field","saving csv file","Save("+RReporting.StringMessage(sFile,true)+","+(bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty?"TAB as newline mode":"BR with marker as newline mode")+"){Row:title; Column:"+ColAbs+"}");
						}
						sField+=RString.SafeString(FieldDataNow,false);
						if (bExtendedTitleColumns) {
							string sMeta=GetForcedMeta(ColAbs);
							if (sMeta!=null) {
								sMeta=RString.SafeString(sMeta,false);
								sMeta=RString.RemoveEndsWhiteSpace(sMeta);
								if (!sMeta.StartsWith("{")) {
									sMeta=RString.Replace(sMeta,"{","");
									sMeta="{"+sMeta;
								}
								if (!sMeta.EndsWith("}")) {
									sMeta=RString.Replace(sMeta,"}","");
									sMeta+="}";
								}
								sField+=sMeta;
							}//end if metadata
						}//end if bExtendedTitleColumns
						sTitles+=((ColRel!=0)?",":"")+RTable.LiteralFieldToCSVField(sField,this.cFieldDelimiter,this.cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty);
						ColAbs++;
					}//end for field (column header)
					fsDest.WriteLine(sTitles);
				}//end if Title Row is not blank
				Console.Error.Write("Writing row range "+RowStart+" to "+(RowStart+RowCount-1)+" of "+iRows+" (total "+0+" to "+(iRows-1)+")...");
				int RowAbs=RowStart;
				for (int RowRel=0; RowRel<RowCount&&RowAbs<iRows; RowRel++) {
					fsDest.WriteLine(RowToCSVLine(RowAbs,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty,ColStart,ColCount));
					RowAbs++;
				}
				fsDest.Close();
				Console.Error.WriteLine("done.");
				bGood=true;
			}
			catch (Exception exn) {
				Console.Error.WriteLine("Could not save table to \""+sFile+"\":");
				Console.Error.WriteLine(exn.ToString());
				bGood=false;
				try { fsDest.Close(); }
				catch (Exception exn2) {
					RReporting.ShowExn(exn2,"closing file after exception","rtable Load");
				}
			}
			return bGood;
		}//end SaveChunk
		}//end Delete_AllWithMarker
		public bool Save(string sFile, bool bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty, bool Set_bSaveMetaDataInTitleRow) {
			if (sLastFile==sFileUnknown) {
				sLastFile=sFile;
				if (sLastFile==null) sLastFile="";
			}
			bSaveMetaDataInTitleRow=Set_bSaveMetaDataInTitleRow;
			StreamWriter fsDest=null;
			bool bGood=false;
			//int iLines=0;
			Delete_AllWithMarker();
			RecheckIntegrity();
			try {
				fsDest=new StreamWriter(sFile);
				if (TitleRowIsNonBlank) {
					//fsDest.WriteLine(teTitles.ToCSVLine(cFieldDelimiter,cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty));
					string sTitles="";//cumulative
					string sField="";//cumulative
					for (int iCol=0; iCol<teTitles.Columns; iCol++) {
						sField="";//sField=RString.SafeString(GetForcedType(iCol),false);//old way
						if (bSaveMetaDataInTitleRow) sField=RString.SafeString(GetForcedType(iCol),false);
						if (sField!="") sField+=" ";
						string FieldDataNow=teTitles.Field(iCol);
						if (FieldDataNow==null) {
							RReporting.ShowErr("Can't access field","saving csv file","Save("+RReporting.StringMessage(sFile,true)+","+(bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty?"TAB as newline mode":"BR with marker as newline mode")+"){Row:title; Column:"+iCol+"}");
						}
						sField+=RString.SafeString(FieldDataNow,false);
						if (bSaveMetaDataInTitleRow) {
						string sMeta=GetForcedMeta(iCol);
							if (sMeta!=null) {
								sMeta=RString.SafeString(sMeta,false);
								sMeta=RString.RemoveEndsWhiteSpace(sMeta);
								if (!sMeta.StartsWith("{")) {
									sMeta=RString.Replace(sMeta,"{","");
									sMeta="{"+sMeta;
								}
								if (!sMeta.EndsWith("}")) {
									sMeta=RString.Replace(sMeta,"}","");
									sMeta+="}";
								}
								sField+=sMeta;
							}//end if metadata
						}//end if bSaveMetaDataInTitleRow
						sTitles+=((iCol!=0)?",":"")+RTable.LiteralFieldToCSVField(sField,this.cFieldDelimiter,this.cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty);
					}//end for column title iCol
					fsDest.WriteLine(sTitles);
				}
				Console.Error.Write("Writing "+iRows+" rows...");
				for (int iNow=0; iNow<iRows; iNow++) {
					fsDest.WriteLine(RowToCSVLine(iNow,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty));
				}
				fsDest.Close();
				Console.Error.WriteLine("done.");
				bGood=true;
			}
			catch (Exception exn) {
				Console.Error.WriteLine("Could not save table to \""+sFile+"\":");
				Console.Error.WriteLine(exn.ToString());
				bGood=false;
				try { fsDest.Close(); }
				catch (Exception exn2) {
					RReporting.ShowExn(exn2,"closing file after exception","rtable Load");
				}
			}
			return bGood;
		}//end Save