private List<MemberDataWrapper> GetMembers(CellSetData cs_descr)
        {
            List<MemberDataWrapper> result = new List<MemberDataWrapper>();
            if (cs_descr != null)
            {
                // Сами элементы - по оси 0
                // По оси 1 - св-ва элементов
                if (cs_descr.Axes.Count > 0)
                {
                    int colIndex = 0;
                    foreach (PositionData posColumn in cs_descr.Axes[0].Positions)
                    {
                        if (posColumn.Members.Count > 0)
                        {
                            MemberDataWrapper wrapper = new MemberDataWrapper(cs_descr.Axes[0].Members[posColumn.Members[0].Id]);

                            if (cs_descr.Axes.Count > 1)
                            {
                                int rowIndex = 0;
                                foreach (PositionData posRow in cs_descr.Axes[1].Positions)
                                {
                                    if (posRow.Members.Count > 0)
                                    {
                                        PropertyData prop = new PropertyData();
                                        prop.Name = cs_descr.Axes[1].Members[posRow.Members[0].Id].Caption;

                                        // Название свойства имеет специальный вид -IsDataMember-
                                        // В качестве названия будем использовать подстроку между символами "-"
                                        //String caption = posRow.Members[0].Caption;
                                        //if (caption.StartsWith("-") && caption.EndsWith("-"))
                                        //    caption = caption.Trim('-');

                                        // Если такого атрибута нет, то будет исключение
                                        CellData cell_descr = null;
                                        try
                                        {
                                            cell_descr = cs_descr.GetCellDescription(colIndex, rowIndex);
                                        }
                                        catch (AdomdErrorResponseException)
                                        {
                                        }

                                        if (cell_descr != null && cell_descr.Value != CellValueData.Empty && !cell_descr.Value.IsError)
                                        {
                                            prop.Value = cell_descr.Value.Value;
                                            wrapper.Member.MemberProperties.Add(prop);
                                        }
                                    }
                                    rowIndex++;
                                }
                            }

                            result.Add(wrapper);
                        }
                        colIndex++;
                    }
                }
            }
            return result;
        }
        public CellValueData GetValue(params int[] index)
        {
            if (CS == null)
            {
                return CellValueData.Empty;
            }

            int[] indexVector = new int[CS.Axes.Count];
            for (int i = 0; i < indexVector.Length; i++)
            {
                indexVector[i] = 0;
            }
            index.CopyTo(indexVector, 0);

            Cell cell = null;
            try
            {
                cell = CS[indexVector];
            }
            catch (ArgumentOutOfRangeException)
            {
                return CellValueData.Empty;
            }
            if (cell != null)
            {
                object value = null;
                string displayName = string.Empty;

                try
                {
                    displayName = cell.FormattedValue;
                }
                catch (Exception exc)
                {
                    displayName = CellValueData.ERROR;
                }

                try
                {
                    value = cell.Value;
                }
                catch (Exception exc)
                {
                    value = exc.ToString();
                }

                if (string.IsNullOrEmpty(displayName))
                {
                    if (value == null)
                    {
                        displayName = String.Empty;
                    }
                    else
                    {
                        displayName = value.ToString();
                    }
                }
                
                CellValueData res = new CellValueData(value, displayName);

                foreach (CellProperty prop in cell.CellProperties)
                {
                    PropertyData property = new PropertyData(prop.Name, null);
                    try
                    {
                        property.Value = prop.Value;
                    }
                    catch (Microsoft.AnalysisServices.AdomdClient.AdomdErrorResponseException ex)
                    {
                        property.Value = ex.ToString();
                    }
                    res.Properties.Add(property);
                }

                return res;
            }

            return null;
        }
        public String GetText(MemberVisualizationTypes type)
        {
            String res = String.Empty;

            String key0 = String.Empty;

            if (type == MemberVisualizationTypes.Key ||
                type == MemberVisualizationTypes.KeyAndCaption)
            {
                PropertyData prop = GetMemberProperty(KEY0_PROPERTY);
                if (prop == null)
                {
                    // Пока что оставили для совместимости с вин-версией
                    prop = GetMemberProperty(MemberData.KEY0_PROPERTY);
                }
                if (prop != null)
                {
                    if (prop.Value != null)
                    {
                        key0 = prop.Value.ToString();
                    }
                    else
                    {
                        // в режиме отображения кодов вместо null нужно светить Caption,  а то получается когда в таблице несколько вычисляемых элементов у всех их светится null (ПФ)
                        // key0 = "null";
                    }
                }
            }

            // Определяем что именно нужно светить в контроле
            switch (type)
            {
            case MemberVisualizationTypes.Caption:
                res = Caption;
                break;

            case MemberVisualizationTypes.Key:
                // Для элементов уровня ALL вместо ключа 0 (который никак нельзя поменять) отображаем Caption
                if (LevelDepth == 0 && !String.IsNullOrEmpty(LevelName) && LevelName.ToLower().Contains(".[(all)]"))
                {
                    res = Caption;
                }
                else
                {
                    //Если ключ в запросе не получался, то выводим просто Caption
                    if (!String.IsNullOrEmpty(key0))
                    {
                        res = key0;
                    }
                    else
                    {
                        res = Caption;
                    }
                }
                break;

            case MemberVisualizationTypes.KeyAndCaption:
                // Для элементов уровня ALL вместо ключа 0 (который никак нельзя поменять) отображаем Caption
                if (LevelDepth == 0 && !String.IsNullOrEmpty(LevelName) && LevelName.ToLower().Contains(".[(all)]"))
                {
                    res = Caption;
                }
                else
                {
                    //Если ключ в запросе не получался, то выводим просто Caption
                    if (!String.IsNullOrEmpty(key0))
                    {
                        res = key0 + " " + Caption;
                    }
                    else
                    {
                        res = Caption;
                    }
                }
                break;

            case MemberVisualizationTypes.UniqueName:
                res = UniqueName;
                break;

            default:
                res = Caption;
                break;
            }
            return(res);
        }
        /// <summary>
        /// Формирует описание для элемента
        /// </summary>
        /// <param name="member"></param>
        /// <returns></returns>
        public MemberData CreateMemberDescription(Member member)
        {
            if (member == null)
                return null;
            MemberData info = new MemberData();
            info.Caption = member.Caption;
            info.ChildCount = member.ChildCount;
            info.Description = member.Description;
            info.DrilledDown = member.DrilledDown;
            info.LevelDepth = member.LevelDepth;
            info.LevelName = member.LevelName;
            info.Name = member.Name;
            info.ParentSameAsPrevious = member.ParentSameAsPrevious;

            String hierarchyUniqueName = GetMemberPropertyValue(member, "HIERARCHY_UNIQUE_NAME");
            if (hierarchyUniqueName != null)
            {
                info.HierarchyUniqueName = hierarchyUniqueName;
            }
            else
            {
                if (m_HierarchiesToLevelsCache.ContainsKey(info.LevelName))
                {
                    info.HierarchyUniqueName = m_HierarchiesToLevelsCache[info.LevelName];
                }
                else
                {
                    try
                    {
                        info.HierarchyUniqueName = member.ParentLevel.ParentHierarchy.UniqueName;
                    }
                    catch (System.InvalidOperationException)
                    {
                        info.HierarchyUniqueName = String.Empty;
                    }

                    m_HierarchiesToLevelsCache[info.LevelName] = info.HierarchyUniqueName;
                }
            }

            info.UniqueName = member.UniqueName;

            // Свойства
            foreach (Property prop in member.Properties)
            {
                PropertyData property = new PropertyData(prop.Name, null);
                try
                {
                    property.Value = prop.Value;
                }
                catch (Microsoft.AnalysisServices.AdomdClient.AdomdErrorResponseException ex)
                {
                    property.Value = ex.ToString();
                }
                info.Properties.Add(property);
            }

            foreach (MemberProperty mp in member.MemberProperties)
            {
                PropertyData property = new PropertyData(mp.Name, null);
                try
                {
                    property.Value = mp.Value;
                }
                catch (Microsoft.AnalysisServices.AdomdClient.AdomdErrorResponseException ex)
                {
                    property.Value = ex.ToString();
                }
                info.MemberProperties.Add(property);
            }
            return info;
        }
        internal void DeserializeData(string DataStr)
        {
            var cellDatas = Jayrock.Json.Conversion.JsonConvert.Import(DataStr) as JsonArray;
            var Values = cellDatas.GetArray(0);
            var DisplayValues = cellDatas.GetArray(1);
            var Styles = cellDatas.GetArray(2);
            int axes0Len = this.Axes.Count > 0 ? this.Axes[0].Positions.Count : 0;
            int axes1Len = this.Axes.Count > 1 ? this.Axes[1].Positions.Count : 0;
            var PropNames = cellDatas[cellDatas.Length - 1] as JsonArray;
            int CellOrdinal = 0;

            int cellsCount = Values.Count;
            for (int j = 0; j < cellsCount; j++)
            {
                var cellData = new CellData();
                cellData.Axis0_Coord = axes0Len > 0 ? j % axes0Len : -1;    // axes0Len может быть 0 и при этом будет одна ячейка (дефолтная). И осей при этом в CellSet нету.
                cellData.Axis1_Coord = axes1Len > 0 ? j / axes0Len : -1;
                var cellValueData = new CellValueData();
                var prop = new PropertyData("CellOrdinal", CellOrdinal);
                cellValueData.Properties.Add(prop);
                object val = ConvertFromJson(Values[CellOrdinal]);
                cellValueData.Value = val;
                prop = new PropertyData("VALUE", val);
                cellValueData.Properties.Add(prop);
                var props = cellDatas.GetArray(3 + Styles.GetInt32(CellOrdinal));
                string FORMAT_STRING = null;
                for (int k = 0; k < PropNames.Length; k++)
                {
                    var propName = PropNames[k].ToString();
                    //if (propName == "FORMAT_STRING")
                    //    FORMAT_STRING = (string)propval;
                    prop = new PropertyData(propName, ConvertFromJson(props[k]));
                    cellValueData.Properties.Add(prop);
                }

                //if (val == null)
                //    cellValueData.DisplayValue = null;
                //else if (FORMAT_STRING != null)
                //    cellValueData.DisplayValue = ((double)val).ToString(FORMAT_STRING);
                //else
                //    cellValueData.DisplayValue = val.ToString();
                cellValueData.DisplayValue = DisplayValues[CellOrdinal++].ToString();

                prop = new PropertyData("FORMATTED_VALUE", cellValueData.DisplayValue);
                cellValueData.Properties.Add(prop);
                cellData.Value = cellValueData;
                Cells.Add(cellData);
            }
        }