Skip to content

insert_column with existing styled cell doesn't set cell @worksheet, causing failure in LegacyCell#validate_worksheet #441

Open

Description

@dmolesUC

From the RubyXL::WorksheetConvenienceMethods#insert_column source code, it looks like it should:

c = RubyXL::Cell.new(:style_index => old_cell.style_index, :worksheet => self,
                     :row => row_index, :column => column_index,
                     :datatype => RubyXL::DataType::SHARED_STRING)

but AFAICT that worksheet param never gets used.

Steps to reproduce

  1. Create a new worksheet
  2. Add a cell
  3. Style the cell
  4. Insert a column at the index of the cell
  5. Get the first cell from the inserted column
  6. Call change_contents on the cell

Expected

  • Contents are changed

Actual

  • RuntimeError: Cell #<RubyXL::Cell:0x000000010561b808> is not in worksheet

Minimal example

#!/usr/bin/env ruby

require 'rubyXL'
require 'rubyXL/convenience_methods'

worksheet = RubyXL::Workbook.new.worksheets[0]

cell = worksheet.add_cell(0, 0, 'test 1')
cell.change_font_bold(true)
added_cell = worksheet[0][0]
added_cell_ws = added_cell.instance_variable_get(:@worksheet)

worksheet.insert_column(0)
inserted_cell = worksheet[0][0]
inserted_cell_ws = inserted_cell.instance_variable_get(:@worksheet)

# Uncomment to see the underlying problem
# puts "original worksheet:       #{worksheet || '<nil>'}"
# puts "added cell @worksheet:    #{added_cell_ws || '<nil>'}"
# puts "inserted cell @worksheet: #{inserted_cell_ws || '<nil>'}"

added_cell.change_contents('test 2')
inserted_cell.change_contents('test 3')

Raises:

/Users/david/.rvm/gems/ruby-3.1.2/gems/rubyXL-3.4.25/lib/rubyXL/cell.rb:24:in `validate_worksheet': Cell #<RubyXL::Cell:0x0000000106c01c30> is not in worksheet  (RuntimeError)
	from /Users/david/.rvm/gems/ruby-3.1.2/gems/rubyXL-3.4.25/lib/rubyXL/convenience_methods/cell.rb:4:in `change_contents'
	from /tmp/rubyxl.rb:23:in `<main>'

Activity

  1. dmolesUC commented on Apr 26, 2023

    @dmolesUC
    Author

    Workaround:

    module RubyXL
      class Cell
        def initialize(params = nil)
          super
          @worksheet ||= params[:worksheet] if params.respond_to?(:[])
        end
      end
    end

    Updated to add:

    If you have multiple rows, LegacyCell#validate_worksheet will still fail even with the above, due to row not getting set, either. Updated workaround:

    module RubyXL
      class Cell
        def initialize(params = nil)
          super
      
          if params.respond_to?(:[])
            @worksheet ||= params[:worksheet] 
            self.row ||= params[:row] # note: not an instance variable
          end
        end
      end
    end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions