I’m using Driving Gameplay with Data from Excel - Unreal Engine as a guideline to set up a CSV with a bunch of common names so I can randomly generate character names at need. The CSV imports cleanly, and I have some UDataTable* nameTable correctly pointing at the CSV, where each row is stored a custom struct:
The guide I linked suggests using UDataTable::FindRow() to access specific rows, but I don’t want any specific row, I’d just like to grab a random name by iterating through the entire CSV, adding each struct to some TArray<FNameLookupTable> myNameStructs, then selecting a string from a random member of my array.
Is there a clean way to do this? As an alternative I could use a const to hardcode the length of my table and do something like UDataTable->FindRow(FMath::RandRange(0,lastRow), but that seems clunky and inelegant.
Hi, UDataTable has the function you need TArray<FName> GetRowNames() const, you should be able to do what you want with this. There is also UDataTableFunctionLibrary is you need BlueprintCallable functions.
Is there a way to use GetRowNames for any other row in the table, though? My table has two rows, one for the row ID, and one with the fstring data, kinda like this:
stringFirstName
1 Bob
2 Joe
3 Larry
And so forth. GetRowNames compiles and iterates, but it returns an array of my row IDs, not of the actual FString names.
Yeah of course. So every row inside the DataTable is a struct, to get this struct you use the function FindRow(FName). To get the name you use GetRowNames(). FindRow() returns a pointer to your struct.
If you just need to iterate over whole UDataTable, there is a simpler way:
UDataTable* DataTable;
for(auto it : DataTable->RowMap)
{
// it.Key has the key from first column of the CSV file
// it.Value has a pointer to a struct of data. You can safely cast it to your actual type, e.g FMyStruct* data = (FMyStruct*)(it.Value);
}
Well, can you please help … I import csv file,to engine. Make a new C++ class from DataTable , include in .h file of my another class and declare variable of it.
How can I iterate through the values thou? …
Feel free to just start your own when you have a question in the future, rather than bumping a 2 year old thread.
To answer you’re question, give this a shot:
for(auto it : ItemData->RowData)
{
// As noted above, it.Key will get you the name of your column, it.Value will be a pointer to whatever data you are storing.
}
… many many thanks for your respond. It`s been 6 hrs I’m struggling with this. well, not sure why your solution doesn’t work. Here is my question (as you advised), just post it now. Please check if you have time…
For future reference to anyone who comes across this thread like I did. As of 4.21 you can no longer access RowMap directly, it’s been protected, instead use GetRowMap()
UDataTable* DataTable;
for(auto it : DataTable->GetRowMap())
for (auto& data : DataTable->GetRowMap())
{
FName name = data.Key;
FMyStruct* MyStruct = reinterpret_cast<FMyStruct*>(data.Value);
// do something with name. and MyStruct->
}
Since internally it is simply a TMAP of fname and a generic pointer.
It is interesting to see that they used a uint8* instead of a void* to indicate a generic pointer.