//=============================================================================
        // Add beam to m_BeamMaxLoadDictionary.
        // maxBeamSpan meanth beam length without Rack.INNER_LENGTH_ADDITIONAL_GAP.
        public bool AddBeam(double maxBeamSpan, double maxBeamLoad, RackBeam beam)
        {
            if (Utils.FLE(maxBeamSpan, 0.0) || Utils.FLE(maxBeamLoad, 0.0) || beam == null)
            {
                return(false);
            }

            if (!m_BeamMaxLoadDictionary.ContainsKey(maxBeamSpan))
            {
                m_BeamMaxLoadDictionary[maxBeamSpan] = new SortedDictionary <double, List <RackBeam> >();
            }

            if (!m_BeamMaxLoadDictionary[maxBeamSpan].ContainsKey(maxBeamLoad))
            {
                m_BeamMaxLoadDictionary[maxBeamSpan][maxBeamLoad] = new List <RackBeam>();
            }

            // Probably this beam already exists in the list.
            if (m_BeamMaxLoadDictionary[maxBeamSpan][maxBeamLoad].Contains(beam))
            {
                return(false);
            }

            m_BeamMaxLoadDictionary[maxBeamSpan][maxBeamLoad].Add(beam);
            return(true);
        }
        private static void _ReadBeamWeightSheet(Microsoft.Office.Interop.Excel._Worksheet beamWeightSheet)
        {
            if (beamWeightSheet == null)
            {
                return;
            }

            try
            {
                m_BeamsList.Clear();

                // Data structure
                // column 1(A) - beam name
                // column 2(B) - beam weight for 1 meter
                // column 3(C) - two end connectors weight

                Microsoft.Office.Interop.Excel.Range xlRange = beamWeightSheet.UsedRange;

                // Read data from the rows.
                // If there are 1 empty row then break data read.
                int iMaxEmptyRowsCellCount = 1;
                int iEmptyRowCellCount     = 0;
                //
                for (int iRow = BEAMWEIGHT_SHEET_START_ROW_INDEX + 1; iRow < 1000; ++iRow)
                {
                    if (iEmptyRowCellCount == iMaxEmptyRowsCellCount)
                    {
                        break;
                    }

                    string strBeamName = string.Empty;
                    // Beam name
                    object objBeamName = xlRange[iRow, 1].Value2;
                    if (objBeamName == null)
                    {
                        ++iEmptyRowCellCount;
                        continue;
                    }
                    else
                    {
                        strBeamName = objBeamName.ToString();
                    }

                    double weightPerMeter = 0.0;
                    // Weight per meter
                    object objWeightPerMeter = xlRange[iRow, 2].Value2;
                    if (objWeightPerMeter == null)
                    {
                        ++iEmptyRowCellCount;
                        continue;
                    }
                    else
                    {
                        try
                        {
                            weightPerMeter = Convert.ToDouble(objWeightPerMeter);
                            if (Utils.FLE(weightPerMeter, 0.0))
                            {
                                continue;
                            }
                        }
                        catch
                        {
                            continue;
                        }
                    }

                    double endConnWeight = 0.0;
                    // Both end connectors weight
                    object objEndConnWeight = xlRange[iRow, 3].Value2;
                    if (objEndConnWeight == null)
                    {
                        ++iEmptyRowCellCount;
                        continue;
                    }
                    else
                    {
                        try
                        {
                            endConnWeight = Convert.ToDouble(objEndConnWeight);
                            if (Utils.FLE(endConnWeight, 0.0))
                            {
                                continue;
                            }
                        }
                        catch
                        {
                            continue;
                        }
                    }

                    iEmptyRowCellCount = 0;

                    // Add beam
                    if (!string.IsNullOrEmpty(strBeamName) && Utils.FGT(weightPerMeter, 0.0) && Utils.FGT(endConnWeight, 0.0))
                    {
                        // try to find beam with the same name
                        RackBeam foundBeam = m_BeamsList.FirstOrDefault(beam => beam != null && beam.Name == strBeamName);
                        if (foundBeam != null)
                        {
                            continue;
                        }

                        m_BeamsList.Add(new RackBeam(strBeamName, weightPerMeter, endConnWeight));
                    }
                }
            }
            catch { }
        }
        private static void _ReadBeamSheet(Microsoft.Office.Interop.Excel._Worksheet beamSheet)
        {
            if (beamSheet == null)
            {
                return;
            }

            try
            {
                m_ReallyUsedBeamsList.Clear();

                // Data structure
                // column 1(A) - column system name
                // column 2(B) - max beam span
                // all other columns contains beams names with MaxLoad

                Microsoft.Office.Interop.Excel.Range xlRange = beamSheet.UsedRange;

                // Find maximum column index - find the first column with empty [3;index + 1] cell
                int iMaxColumnIndex = -1;
                // Column index to beam dictionary.
                Dictionary <int, RackBeam> columnIndexToBeamDict = new Dictionary <int, RackBeam>();
                // Fill dictionary
                for (int i = 3; i <= 100; ++i)
                {
                    object objColumnName = xlRange[2, i].Value2;
                    if (objColumnName == null)
                    {
                        break;
                    }
                    else
                    {
                        string strColumnName = objColumnName.ToString();
                        if (!string.IsNullOrEmpty(strColumnName))
                        {
                            // try to find this beam in m_BeamsList
                            RackBeam foundBeam = m_BeamsList.FirstOrDefault(beam => beam != null && beam.Name == strColumnName);
                            if (foundBeam == null)
                            {
                                continue;
                            }

                            columnIndexToBeamDict[i] = foundBeam;
                            iMaxColumnIndex          = i;
                        }
                    }
                }
                //
                if (iMaxColumnIndex < 0)
                {
                    return;
                }


                // Read data from the rows.
                // If there are 3 empty row then break data read.
                int iMaxEmptyRowsCellCount = 3;
                int iEmptyRowCellCount     = 0;
                //
                for (int iRow = BEAM_SHEET_START_ROW_INDEX + 1; iRow < 10000; ++iRow)
                {
                    if (iEmptyRowCellCount == iMaxEmptyRowsCellCount)
                    {
                        break;
                    }

                    // read column name
                    RackColumn foundColumn  = null;
                    object     obColumnName = xlRange[iRow, 1].Value2;
                    if (obColumnName == null)
                    {
                        ++iEmptyRowCellCount;
                        continue;
                    }
                    else
                    {
                        string strColumnName = obColumnName.ToString();
                        if (string.IsNullOrEmpty(strColumnName))
                        {
                            ++iEmptyRowCellCount;
                            continue;
                        }
                        // Column should exist in m_RacksColumnsList.
                        foundColumn = m_RacksColumnsList.FirstOrDefault(c => c != null && c.Name == strColumnName);
                        if (foundColumn == null)
                        {
                            continue;
                        }
                    }

                    // read max beam span
                    double rMaxBeamSpan   = 0.0;
                    object objMaxBeamSpan = xlRange[iRow, 2].Value2;
                    if (objMaxBeamSpan == null)
                    {
                        continue;
                    }
                    else
                    {
                        try
                        {
                            rMaxBeamSpan = Convert.ToDouble(objMaxBeamSpan);
                        }
                        catch
                        {
                            continue;
                        }
                    }
                    if (Utils.FLE(rMaxBeamSpan, 0.0))
                    {
                        continue;
                    }

                    // Read beams
                    for (int iColumn = 3; iColumn <= iMaxColumnIndex; ++iColumn)
                    {
                        RackBeam foundBeam = null;
                        if (columnIndexToBeamDict.ContainsKey(iColumn))
                        {
                            foundBeam = columnIndexToBeamDict[iColumn];
                        }
                        if (foundBeam == null)
                        {
                            continue;
                        }

                        // Read max beam load
                        object objMaxBeamLoad = xlRange[iRow, iColumn].Value2;
                        if (objMaxBeamLoad == null)
                        {
                            continue;
                        }
                        else
                        {
                            try
                            {
                                int maxBeamLoad = Convert.ToInt32(objMaxBeamLoad);
                                if (foundColumn.AddBeam(rMaxBeamSpan, maxBeamLoad, foundBeam) && !m_ReallyUsedBeamsList.Contains(foundBeam))
                                {
                                    m_ReallyUsedBeamsList.Add(foundBeam);
                                }
                            }
                            catch { }
                        }
                    }

                    iEmptyRowCellCount = 0;
                }
            }
            catch { }
        }