--- a/sympy/matrices/expressions/blockmatrix.py
+++ b/sympy/matrices/expressions/blockmatrix.py
@@ -232,19 +232,33 @@ class BlockMatrix(BlockDiagMatrix):
 
     def _entry(self, i, j, **kwargs):
-        from sympy import floor
+        from sympy.functions.elementary.piecewise import Piecewise
+        from sympy.core.numbers import Integer
+        from sympy.core.logic import fuzzy_not
+
+        # First, check if all block dimensions are concrete integers
         rowblocksizes = self.rowblocksizes
         colblocksizes = self.colblocksizes
 
-        row_block = 0
-        col_block = 0
-        cumul_row = 0
-        cumul_col = 0
-        for i_sum in rowblocksizes:
-            if i < cumul_row + i_sum:
-                break
-            cumul_row += i_sum
-            row_block += 1
-        for j_sum in colblocksizes:
-            if j < cumul_col + j_sum:
-                break
-            cumul_col += j_sum
-            col_block += 1
+        # Calculate cumulative offsets
+        row_offset = 0
+        for row_block, row_size in enumerate(rowblocksizes):
+            # Check if i < row_offset + row_size is definitely true
+            if (i - row_offset).is_nonnegative is False:
+                # i < row_offset, went too far (shouldn't happen normally)
+                from sympy.matrices.expressions.matexpr import MatrixElement
+                return MatrixElement(self, i, j)
+            if (i - row_offset - row_size).is_nonnegative is False:
+                # i < row_offset + row_size, found the right block
+                break
+            elif (i - row_offset - row_size).is_nonnegative is None:
+                # Can't determine, return unevaluated
+                from sympy.matrices.expressions.matexpr import MatrixElement
+                return MatrixElement(self, i, j)
+            row_offset += row_size
+        else:
+            # Ran off the end
+            from sympy.matrices.expressions.matexpr import MatrixElement
+            return MatrixElement(self, i, j)
 
-        return self.blocks[row_block, col_block][i - cumul_row, j - cumul_col]
+        col_offset = 0
+        for col_block, col_size in enumerate(colblocksizes):
+            if (j - col_offset).is_nonnegative is False:
+                from sympy.matrices.expressions.matexpr import MatrixElement
+                return MatrixElement(self, i, j)
+            if (j - col_offset - col_size).is_nonnegative is False:
+                break
+            elif (j - col_offset - col_size).is_nonnegative is None:
+                from sympy.matrices.expressions.matexpr import MatrixElement
+                return MatrixElement(self, i, j)
+            col_offset += col_size
+        else:
+            from sympy.matrices.expressions.matexpr import MatrixElement
+            return MatrixElement(self, i, j)
+
+        return self.blocks[row_block, col_block][i - row_offset, j - col_offset]