Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error creating Array with Google Sheets #16

Closed
JelleDekkers opened this issue Jul 9, 2016 · 8 comments
Closed

Error creating Array with Google Sheets #16

JelleDekkers opened this issue Jul 9, 2016 · 8 comments
Assignees

Comments

@JelleDekkers
Copy link

JelleDekkers commented Jul 9, 2016

Hi there,

I'm getting an error creating an array. I've tried using strings and int dataTypes and I've used tabs, comma's and comma's with one space to seperate my data in my google sheet but nothing seems to work when I download the sheet.

Here's the error:

GDataDB Serialization Exception: Value is not a convertible object: System.String to System.String[] ListEntry LocalName: arraytest
UnityEngine.Debug:LogError(Object)
GDataDB.Impl.Serializer1:Deserialize(ListEntry) (at Assets/QuickSheet/GDataPlugin/Editor/GDataDB/GDataDB/Impl/Serializer.cs:71) GDataDB.Impl.Table1:Find(FeedQuery) (at Assets/QuickSheet/GDataPlugin/Editor/GDataDB/GDataDB/Impl/Table.cs:99)
GDataDB.Impl.Table1:FindAll() (at Assets/QuickSheet/GDataPlugin/Editor/GDataDB/GDataDB/Impl/Table.cs:52) testEditor:Load() (at Assets/Editor/Data/testEditor.cs:67) UnityQuickSheet.BaseGoogleEditor1:OnInspectorGUI() (at Assets/QuickSheet/GDataPlugin/Editor/BaseGoogleEditor.cs:97)
testEditor:OnInspectorGUI() (at Assets/Editor/Data/testEditor.cs:35)
UnityEditor.DockArea:OnGUI()

@JelleDekkers
Copy link
Author

JelleDekkers commented Jul 10, 2016

I was able to resolve this issue myself using the following code in the try catch in the Deserialize function in Serializer.cs:

    try
    {
        // !!supoort array type!!
        if (property.PropertyType.IsArray) {
            // change '\n' to ',' if you want it the array to be split by comma's instead of a new line.
            object[] array = c.Value.Split('\n'); 
            property.SetValue(r, array, null);
         } 
         else {
             var value = ConvertFrom(c.Value, property.PropertyType);
             property.SetValue(r, value, null);
         }
    }

Change the \n to a comma if you want it the array to be split by comma's instead of a new line.

Unfortunatly the array doesn't show in the Unity UI sheet.

@kimsama
Copy link
Owner

kimsama commented Jul 15, 2016

Sorry late for the reply, I've been heavily busy on these days.

Oops, forgot to update google side though excel's one correctly works. :-) Thanks for pointing it out.

By the way, your modification seems to only work for string type. It needs a few more lines to convert various array type (e.g. float, int, long etc.) See ExcelQuery.Deserialize function which can be found in the ExcelQuery.cs file. You can find how it deals with various array type.

Let's me dig it out. It may takes a few days to fix the problem.

Secondly, yes, reflecting array type on the Inspector view is not supported yet. Frankly saying, the reflecting code was written long time ago even with Unity 3.x version so it needs to be entirely changed with SerializedObject and SerializedProperty which are native object of UnityEditor not with ExposeProperty custom attribute. And it also needs some nice approach for reflecting array type though it is not difficult. Not sure when I can get some free time for that work. So until that fix will be arrived, you may need to have some patient. :-)

Any suggestions or ideas are always welcome.

Cheers,

-Kim

@kimsama kimsama self-assigned this Jul 15, 2016
@JelleDekkers
Copy link
Author

JelleDekkers commented Jul 16, 2016

Thanks for replying. Better late than never :)

Since my last comment I was able to get all types of array working, It's a bit hacky but it works.

This goes in the Deserialize function in Serializer.cs:

    try
    {
        if (property.PropertyType.IsArray) 
        {
            if (property.PropertyType.GetElementType().IsEnum) 
            {
                var values = c.Value.Split('\n')
                                      .Select(s => s.Replace(" ", string.Empty))
                                      .Select(i => Enum.Parse(property.PropertyType.GetElementType(), i))
                                      .ToArray();

                Array array = (Array)Activator.CreateInstance(property.PropertyType, values.Length);

                // copy the object values to the array
                int l = 0;
                foreach (var value in values) {
                    array.SetValue(value, l++);
                }

                property.SetValue(r, array, null);
            } 
            else {
                object[] temp = c.Value.Split('\n');
                Array array = (Array)Activator.CreateInstance(property.PropertyType, temp.Length);

                for (int i = 0; i < array.Length; i++) {
                    array.SetValue(Convert.ChangeType(temp[i], property.PropertyType.GetElementType()), i);
                }

                property.SetValue(r, array, null);
            }
        } 
        else {
            object value = new object();
            if (property.PropertyType.IsEnum) {
            {
                value = c.Value.Replace(" ", string.Empty);
                value = Enum.Parse(property.PropertyType, value.ToString());
            } 
            else {
                value = ConvertFrom(c.Value, property.PropertyType);
            }

            property.SetValue(r, value, null);
        }
    }

@kimsama
Copy link
Owner

kimsama commented Jul 17, 2016

By the way, could you show me the spreadsheet which was tested for the above code snip?

-Kim

@JelleDekkers
Copy link
Author

JelleDekkers commented Jul 17, 2016

I'd rather not show you the entire spreadsheet as I have about 4 different sheets. Here is a small snippet where name is a string and productsRequired is an array of enums, seperated by a newline.


ID  Name                ProductsRequired    
0   Settler             Fish
                        Linnen Garments
                        Cider
1   Peasant             Bread
                        Beer
                        Leather Jerkins
                        Salt
                        Spices

@kimsama
Copy link
Owner

kimsama commented Jul 19, 2016

That's enough. I just wonder how you set the array elements in the spreadsheet.

Thanks.

-Kim

kimsama added a commit that referenced this issue Aug 3, 2016
…t works with ',' for array elements in a cell without last comma (not like excel version - e.g. 1,2,3,4 not 1,2,3,4, )
@kimsama
Copy link
Owner

kimsama commented Aug 4, 2016

Fixed and applied now in the googledriver-fix branch.

@kimsama
Copy link
Owner

kimsama commented Aug 9, 2016

merged into master.

@kimsama kimsama closed this as completed Aug 9, 2016
zzxiang pushed a commit to MokaGames/Unity-QuickSheet that referenced this issue Jan 23, 2019
…heet. It works with ',' for array elements in a cell without last comma (not like excel version - e.g. 1,2,3,4 not 1,2,3,4, )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants