// Author: Michael Boroden

// Version 1.0

// Used for tag generation to import into RSLogix 5000.

// Input file: Column A: base tag name

// Output file: Import tag CSV format for RSLogix 5000.

// Note: This source code is licensed under The Code Project Open License (CPOL).

using System;

using System.Collections.Generic;

using System.IO;

using System.Text;

using ReadWriteCsv;

class Top

{

static void Main()

{

using (CsvFileReader reader = new CsvFileReader("infile.csv"))

using (CsvFileWriter writer = new CsvFileWriter("outfile.csv"))

{

// Initialize variables.

CsvRow row = new CsvRow();

int counter = 12;

// Read from source file until EOF.

while (reader.ReadRow(row))

{

String[] tag;

tag = row.ToArray();

row.Clear();

// Row 1: ENR

row.Insert(0, "ALIAS"); // Column A

row.Insert(1, ""); // Column B

row.Insert(2, tag[0] + "_ENR"); // Column C

row.Insert(3, ""); // Column D

row.Insert(4, ""); // Column E

row.Insert(5, "YOKO_CMD[" + counter++ + "]"); // Column F

row.Insert(6, "(RADIX := Decimal, ExternalAccess := Read/Write)"); // Column G

writer.WriteRow(row);

row.Clear();

// Row 2: ACK

row.Insert(0, "ALIAS"); // Column A

row.Insert(1, ""); // Column B

row.Insert(2, tag[0] + "_ACK"); // Column C

row.Insert(3, ""); // Column D

row.Insert(4, ""); // Column E

row.Insert(5, "YOKO_CMD[" + counter++ + "]"); // Column F

row.Insert(6, "(RADIX := Decimal, ExternalAccess := Read/Write)"); // Column G

writer.WriteRow(row);

row.Clear();

// Row 3: OOS

row.Insert(0, "ALIAS"); // Column A

row.Insert(1, ""); // Column B

row.Insert(2, tag[0] + "_OOS"); // Column C

row.Insert(3, ""); // Column D

row.Insert(4, ""); // Column E

row.Insert(5, "YOKO_CMD[" + counter++ + "]"); // Column F

row.Insert(6, "(RADIX := Decimal, ExternalAccess := Read/Write)"); // Column G

writer.WriteRow(row);

row.Clear();

// Row 4: MOD

row.Insert(0, "ALIAS"); // Column A

row.Insert(1, ""); // Column B

row.Insert(2, tag[0] + "_MOD"); // Column C

row.Insert(3, ""); // Column D

row.Insert(4, ""); // Column E

row.Insert(5, "YOKO_CMD[" + counter++ + "]"); // Column F

row.Insert(6, "(RADIX := Decimal, ExternalAccess := Read/Write)"); // Column G

writer.WriteRow(row);

row.Clear();

}

}

}

}

// ReadWriteCsv.cs taken from template on http://www.codeproject.com/Articles/415732/Reading-and-Writing-CSV-Files-in-Csharp

// It is licensed under The Code Project Open License (CPOL) 1.02

using System;

using System.Collections.Generic;

using System.IO;

using System.Text;

namespace ReadWriteCsv

{

/// <summary>

/// Class to store one CSV row

/// </summary>

public class CsvRow : List<string>

{

public string LineText { get; set; }

}

/// <summary>

/// Class to write data to a CSV file

/// </summary>

public class CsvFileWriter : StreamWriter

{

public CsvFileWriter(Stream stream)

: base(stream)

{

}

public CsvFileWriter(string filename)

: base(filename)

{

}

/// <summary>

/// Writes a single row to a CSV file.

/// </summary>

/// <param name="row">The row to be written</param>

public void WriteRow(CsvRow row)

{

StringBuilder builder = new StringBuilder();

bool firstColumn = true;

foreach (string value in row)

{

// Add separator if this isn't the first value

if (!firstColumn)

builder.Append(',');

// Implement special handling for values that contain comma or quote

// Enclose in quotes and double up any double quotes

if (value.IndexOfAny(new char[] { '"', ',' }) != -1)

builder.AppendFormat("\"{0}\"", value.Replace("\"", "\"\""));

else

builder.Append(value);

firstColumn = false;

}

row.LineText = builder.ToString();

WriteLine(row.LineText);

}

}

/// <summary>

/// Class to read data from a CSV file

/// </summary>

public class CsvFileReader : StreamReader

{

public CsvFileReader(Stream stream)

: base(stream)

{

}

public CsvFileReader(string filename)

: base(filename)

{

}

/// <summary>

/// Reads a row of data from a CSV file

/// </summary>

/// <param name="row"></param>

/// <returns></returns>

public bool ReadRow(CsvRow row)

{

row.LineText = ReadLine();

if (String.IsNullOrEmpty(row.LineText))

return false;

int pos = 0;

int rows = 0;

while (pos < row.LineText.Length)

{

string value;

// Special handling for quoted field

if (row.LineText[pos] == '"')

{

// Skip initial quote

pos++;

// Parse quoted value

int start = pos;

while (pos < row.LineText.Length)

{

// Test for quote character

if (row.LineText[pos] == '"')

{

// Found one

pos++;

// If two quotes together, keep one

// Otherwise, indicates end of value

if (pos >= row.LineText.Length || row.LineText[pos] != '"')

{

pos--;

break;

}

}

pos++;

}

value = row.LineText.Substring(start, pos - start);

value = value.Replace("\"\"", "\"");

}

else

{

// Parse unquoted value

int start = pos;

while (pos < row.LineText.Length && row.LineText[pos] != ',')

pos++;

value = row.LineText.Substring(start, pos - start);

}

// Add field to list

if (rows < row.Count)

row[rows] = value;

else

row.Add(value);

rows++;

// Eat up to and including next comma

while (pos < row.LineText.Length && row.LineText[pos] != ',')

pos++;

if (pos < row.LineText.Length)

pos++;

}

// Delete any unused items

while (row.Count > rows)

row.RemoveAt(rows);

// Return true if any columns read

return (row.Count > 0);

}

}