spars
spars

Reputation: 15

c# Help making values global

so I understand how to make global values and the fact that 1. you shouldn't do it and 2. you cannot use a value that was created in a different "context" however, I'm not sure how to correct this problem in my case. I think it will make sense if you read my code

            //read in Load Query TestCSV
        var sourcePath = @"D:\\Load Query test.csv"; //What is the inital CSV
        var delimiter = ",";
        var firstLineContainsHeaders = true; //CSV has headers
        //creates temp file which takes less time than loading into memory
        var tempPath = Path.Combine(@"D:", Path.GetRandomFileName());
        var lineNumber = 0;

        var splitExpression = new Regex(@"(" + delimiter + @")(?=(?:[^""]|""[^""]*"")*$)");

        using (var writer = new StreamWriter(tempPath))
        using (var reader = new StreamReader(sourcePath))
        {
            string line = null;
            string[] headers = null;
            if (firstLineContainsHeaders)
            {
                line = reader.ReadLine();
                lineNumber++;

                if (string.IsNullOrEmpty(line)) return; // file is empty;

                headers = splitExpression.Split(line).Where(s => s != delimiter).ToArray();

                writer.WriteLine(line); // write the original header to the temp file.
            }
            var i = 0; //used in 2nd while loop later
            string lines = null;//used in next using statement
            while ((line = reader.ReadLine()) != null)
            {
                lineNumber++;

                var columns = splitExpression.Split(line).Where(s => s != delimiter).ToArray();

                //make sure you always have the same number of columns in a line
                if (headers == null) headers = new string[columns.Length];

                if (columns.Length != headers.Length) throw new InvalidOperationException(string.Format("Line {0} is missing one or more columns.", lineNumber));
                string badDate = "Date entered incorrectly";                                    //used in next while loop
                // this while loop will read in the user input dateTime and use that to get the column from the PI server.
                //if the date time is entered incorrectly it will tell the user to try to input the datetime again
                while (i==0)
                {
                    Console.WriteLine("Enter date, ex:16 Jun 8:30 AM 2008, Press enter when done"); //instruct the user in how to enter the date
                    string userInput = Console.ReadLine(); //read in the date the user enters
                    string format = "dd MMM h:mm tt yyyy"; //how the system will read the date entered

                    DateTime dateTime;

                    //if date is entered correctly, parse it, grab the parsed value dateTime and exit loop
                    if (DateTime.TryParseExact(userInput, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
                    {                           
                        i = 1; //set the flag to exit while loop
                    }
                    //if input is bad return "Date entered incorrectly and run the loop again
                    else
                    {
                        Console.WriteLine(badDate);
                        i=0; //set the flag to run the loop again
                    }
                }
                var del = ",";                                                                  //used in next using statement
                var SplitExpression = new Regex(@"(" + del + @")(?=(?:[^""]|""[^""]*"")*$)");   //used in next using statement
                //Use the dateTime from the previous while loop and use it to add each point in "testpts.csv" to "Load Query Test.csv"
                using (StreamReader tags = new StreamReader(@"D:\\testpts.csv"))
                {
                   // string userInput = Console.ReadLine();
                    string format = "dd MMM h:mm tt yyyy";
                    DateTime.TryParseExact(userInput, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime);
                    lines = tags.ReadLine();
                    var columns1 = SplitExpression.Split(lines).Where(s => s != del).ToArray();
                    var point = PIPoint.FindPIPoint(piServer, lines);
                    var value = point.RecordedValue(dateTime);
                    string returnXml = string.Format(@"<value=""{0}"" />", value);
                    columns[15] = columns[15].Replace("0", returnXml); //column the point should be placed in (in Load Query Test.csv)
                }
                //if statement that will replace any extra 0 testpt values with column 13 values
                if (columns[15].Contains("0"))
                {
                    columns[15] = columns[15].Replace("0", columns[13]);
                }

                writer.WriteLine(string.Join(delimiter, columns));
            }

        }

        File.Delete(sourcePath); //delete the original csv
        File.Move(tempPath, sourcePath); //replace the old csv with edited one

        Console.ReadLine();

I'm getting the error in the using statement:

using (StreamReader tags = new StreamReader(@"D:\\testpts.csv"))
                {
                   // string userInput = Console.ReadLine();
                    string format = "dd MMM h:mm tt yyyy";
                    DateTime.TryParseExact(userInput, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime);
                    lines = tags.ReadLine();
                    var columns1 = SplitExpression.Split(lines).Where(s => s != del).ToArray();
                    var point = PIPoint.FindPIPoint(piServer, lines);
                    var value = point.RecordedValue(dateTime);
                    string returnXml = string.Format(@"<value=""{0}"" />", value);
                    columns[15] = columns[15].Replace("0", returnXml); //column the point should be placed in (in Load Query Test.csv)
                }

In this case the dateTime and userInput values are obviously out of context. I need them created in the previous while loop however because I want the user to be able to enter the correct date only once and ensure that it is entered correctly to make sure the script will actually pull data.

Please let me know if there is another way I can order my code or how I can make userInput and dateTime global. Thank you

Upvotes: 0

Views: 95

Answers (2)

Veverke
Veverke

Reputation: 11408

Your problem lies in the "dateTime" variable. "userInput" is fine, the inner using statement has access to the scope of its outer using statement, because the inner one is part of the outer's scope.

The problem is with "dateTime" - the variable is declared inside a while loop, and there is a using block afterwards - after the variable is not available anymore, because the scope was disposed - which references a non existent variable.

Solution: move the declaration of your dateTime variable out of the while. Say, a line before the while's definition.

Upvotes: 1

KarmaEDV
KarmaEDV

Reputation: 1691

Without critisizing your code to much ... here an answer. You should be able to walk yourself from here on

Split the declaration of the variable with it's assignment

string userInput = Console.ReadLine(); 

to

string userInput;
userInput = Console.ReadLine();

Move the declarations (the first line) outside of the outer Loop.

Edit: Please, also have a look at Properties (you may call them globals)

Upvotes: 0

Related Questions