jjones150
jjones150

Reputation: 302

Getting an error and don't understand why

I am at my wits end here. I am writing some procedural code that takes the names of files from an excel worksheet. The code should then find each file recursively starting from a base directory then copy each file to a single location.

My code iterates once then, on the second iteration, produces an error that states that my 'justPath' variable on line 47 cannot be null.

I have posted the code below. Any help is GREATLY appreciated.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
using System.IO;

namespace ExcelManip
{
    class Program
    {
        static void Main(string[] args)
        {        
            Excel.Application xlApp = new Excel.Application();
            Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"C:\Users\employee1234\Desktop\Reload_837_X12_Raw.xlsx", 0, false, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", true, false, 0, true, 1, 0);
            Excel._Worksheet xlWorksheet = (Excel._Worksheet)xlWorkbook.Sheets[4];
            Excel.Range xlRange = xlWorksheet.UsedRange;
            int rowCount = xlRange.Rows.Count;
            int colCount = xlRange.Columns.Count;
            int actualRows = rowCount - 1;
            int y = 0;
            int z = 1;         
            string targetPath = @"C:\Users\employee1234\Desktop\dropfiles";
            for (int count = 11; count <= rowCount; count++){
                var currentIndex = count;
                var yy = y;
                Console.WriteLine(yy);
                string temp = (string)(xlRange.Cells[currentIndex, 2] as Excel.Range).Value2; 
                string[] filePaths = Directory.GetFiles(@"\\fileshare01\Data\subfolder1\subfolder2\", temp, SearchOption.AllDirectories);
                Array.Resize(ref filePaths, filePaths.Length + 1);
                string filePath = filePaths[yy];
                string justPath = Path.GetDirectoryName(filePath);     
                string sourceFile = System.IO.Path.Combine(justPath, temp);                
                string destFile = System.IO.Path.Combine(targetPath, temp);
                Console.WriteLine("File Path " + z+ " of "+ actualRows +" : "+ filePath + "\n");
                System.IO.File.Copy(sourceFile, destFile, true);
                y++;
                z++;
                               }
            xlWorkbook.Save();
            xlWorkbook.Close(0);
            xlApp.Quit();
            GC.Collect();


      }
    }
}

Upvotes: 0

Views: 196

Answers (3)

Sami Kuhmonen
Sami Kuhmonen

Reputation: 31203

The issue is that you have a variable y that you increment every time in the loop. I assume you think that this line appends to the array:

string[] filePaths = Directory.GetFiles(@"\\fileshare01\Data\subfolder1\subfolder2\", temp, SearchOption.AllDirectories);

It doesn't. It creates a new array. So assuming there is only one file with the name you want, the next time you loop y == 1 and you're pointing outside the returned results to the null you appended to the array.

If you want to store the actual paths of the files, you need to define a variable outside the loop and add to that. For example a List<string>. But since you're just copying, this is not needed.

Also, why duplicating variables like yy, currentIndex if they just point to variables y and count which are not modified at all?

And even though you know there is always a file with that name, it still doesn't hurt to actually test for this and when it happens that a file doesn't exist, you can output an error.

Your loop should be more like:

var paths = new List<string>();
for (int count = 11; count <= rowCount; count++){
    string temp = (string)(xlRange.Cells[count, 2] as Excel.Range).Value2; 
    string[] filePaths = Directory.GetFiles(@"\\fileshare01\Data\subfolder1\subfolder2\", temp, SearchOption.AllDirectories);
    if ((filePaths == null) || (filePaths.Length == 0))
    {
      Console.WriteLine("Didn't find file: " + temp);
      continue; // Or break, or exit, or...
    }
    string filePath = filePaths[0];
    // If the temp is a single filename (no globs), you don't even need the next two lines
    string justPath = Path.GetDirectoryName(filePath);     
    string sourceFile = System.IO.Path.Combine(justPath, temp);                
    string destFile = System.IO.Path.Combine(targetPath, temp);
    Console.WriteLine("File Path " + z+ " of "+ actualRows +" : "+ filePath + "\n");
    System.IO.File.Copy(sourceFile, destFile, true);
    paths.Add(sourceFile); // or destFile, or what you want to store
    z++;
}

Upvotes: 1

AccessViolation
AccessViolation

Reputation: 181

Array.Resize(ref filePaths, filePaths.Length + 1); this line appends null string to filePaths array. If yy counter goes that far thats it..

Upvotes: 0

Ospho
Ospho

Reputation: 2796

Path.GetDirectoryName Method from .NET documentation:

Return Value Type: System.String Directory information for path, or null if path denotes a root directory or is null. Returns String.Empty if path does not contain directory information.

Further comment:

In most cases, the string returned by this method consists of all characters in the path up to but not including the last DirectorySeparatorChar or AltDirectorySeparatorChar. If the path consists of a root directory, such as "c:\", null is returned. Note that this method does not support paths using "file:". Because the returned path does not include the DirectorySeparatorChar or AltDirectorySeparatorChar, passing the returned path back into the GetDirectoryName method will result in the truncation of one folder level per subsequent call on the result string. For example, passing the path "C:\Directory\SubDirectory\test.txt" into the GetDirectoryName method will return "C:\Directory\SubDirectory". Passing that string, "C:\Directory\SubDirectory", into GetDirectoryName will result in "C:\Directory".

Upvotes: 1

Related Questions