My code should import some values from an Excel file to a dictionary and then print them out as an xml file. This is a part of my code that is relevant to the problem:
static Dictionary<string, SL_Weapon> dict_Swords_1h = new Dictionary<string, SL_Weapon>();
public static void LoadExcelDataForXML()
{
WorkSheet ws = wb.GetWorkSheet("Swords_1h");
int i = 1;
SL_Weapon generic = new SL_Weapon()
{
Name = ws.Rows[i].Columns[1].ToString(),
Target_ItemID = ws.Rows[i].Columns[0].IntValue,
//+ a bunch of other columns
...
}
void LoadExcel_Swords_1h()
{
ws = wb.GetWorkSheet("Swords_1h");
i = 1;
foreach (var item in ws["B2:B40"])
{
dict_Swords_1h.Add(ws.Rows[i].Columns[1].ToString(), generic);
i++;
}
}
LoadExcel_Swords_1h();
}
static public void WriteToXML()
{
string itemClass = "SL_MeleeWeapon";
string statsHolderClass = "\"SL_WeaponStats\"";
Dictionary<string, SL_Weapon>.ValueCollection swords_1h = dict_Swords_1h.Values;
foreach (SL_Weapon weapon in swords_1h)
{
string path = @"C:\Users\Marcin\Desktop\Outward - Mody Moje\Outward Enhanced - Weapons - Import From Excel\dupa\"+weapon.Name+".xml";
using (StreamWriter writer = new StreamWriter(path))
{
writer.WriteLine(" <Name>" + weapon.Name + "</Name>");
//and a bunch of other stats
...
}
}
}
Now, the problem is that the line ws.Rows[i].Columns[1].ToString()
(which is basically a name of a weapon) that is located in the void LoadExcel_Swords_1h()
method works just fine (meaning i
increments as I want it to, so I get 39 different items from the Excel file), but the same line that is located in the initializer of SL_Weapon generic = new SL_Weapon()
does not increment. So I have 39 different items in my dict_Swords_1h
dictionary, each one has (obviously) a unique Key
that is the name of the weapon from each consecutive row in the Excel file. However all items have identical names (and other stats) which are taken from row 1 in the Excel file, meaning i
does not increment in the Values
part of my Dictionary and always stays at 1.
Why is this happening? I would like i
to increment in both cases so that each weapon has its unique stats loaded from its corresponding row in the Excel file.
I think it's worth mentioning that if I put SL_Weapon generic = new SL_Weapon()
initializer inside the void LoadExcel_Swords_1h()
method not before it, everything works fine. The thing is that I've got more similar methods and I wanted to find a way to avoid repetition. Otherwise I have to repeat the whole initializer code inside each one of those methods.
You need to create a new SL_Weapon for each weapon you are adding to the dictionary. Your nested method LoadExcel_Swords_1h
is unnecessary. Your code can be simplified to use a for loop like this.
public static void LoadExcelDataForXML()
{
//Grab the worksheet
WorkSheet ws = wb.GetWorkSheet("Swords_1h");
//Loop over rows 2 to 40
for (var i = 1; i <= 40; i++)
{
//Create a new instance of weapon from the row
var weapon = new SL_Weapon()
{
Name = ws.Rows[i].Columns[1].ToString(),
Target_ItemID = ws.Rows[i].Columns[0].IntValue,
//+ a bunch of other columns
...
}
//Add the weapon to the dictionary
dict_Swords_1h.Add(weapon.Name, weapon);
}
}
To Address your concern about repetition, you can modify SL_Weapon to accept a constructor argument of type row and pass that into it. When doing so it would look like this
public class SL_Weapon()
{
public SL_Weapon(Row row)
{
Name = row.Columns[1].ToString(),
Target_ItemID = row.Columns[0].IntValue,
...
}
}
Your loop would then look something like this
public static void LoadExcelDataForXML()
{
//Grab the worksheet
WorkSheet ws = wb.GetWorkSheet("Swords_1h");
//Loop over rows 2 to 40
for (var i = 1; i <= 40; i++)
{
//Create a new instance of weapon from the row
var weapon = new SL_Weapon(ws.Rows[i]);
//Add the weapon to the dictionary
dict_Swords_1h.Add(weapon.Name, weapon);
}
}