help copying a value

im trying to copy the value of "b" the moment the button is pressed and save that as the value of "Sh"
until the encoder is turned

buttonState = digitalRead(buttonPin);

    long newPosition = myEnc.read();
    if (newPosition != oldPosition) {
      oldPosition = newPosition;
    }
    float sh = newPosition / 4;
    int b = mydata.b;
    //sh = constrain(sh, 0, 360);
    if (sh > 359) {
      myEnc.write(0);
    }
    if (sh < 0) {
      myEnc.write(1436);
    }

    int Sh = sh;
      if (buttonState == LOW) {
        Sh = b;
      delay(50);
     
    }

Full code

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 10, TXPin = 11;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

// For stats that happen every 5 seconds
unsigned long last = 0UL;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EasyTransferI2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
EasyTransferI2C ET;

#include <Encoder.h>
struct RECEIVE_DATA_STRUCTURE {
  //put your variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  int16_t a;
  int16_t b;
};
RECEIVE_DATA_STRUCTURE mydata;

//define slave i2c address
#define I2C_SLAVE_ADDRESS 9
const int buttonPin = 4;     // the number of the pushbutton pin
// variables will change:
int buttonState = 0;
int lastbuttonState = 0;
int newSh = 0;
int oldSh = 0;
Encoder myEnc(2, 3);
void setup()
{
  Serial.begin(9600);
  ss.begin(GPSBaud);
  pinMode(buttonPin, INPUT);
  Wire.begin(I2C_SLAVE_ADDRESS);
  //start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
  ET.begin(details(mydata), &Wire);
  //define handler function on receiving data
  Wire.onReceive(receive);
  lcd.init();
  lcd.backlight();
  lcd.setCursor (3, 0);
  lcd.print("Autopilot!");
  delay(1500);
  lcd.clear();
}
long oldPosition  = -999;
void loop()
{
  if (ET.receiveData()) {
    Serial.print("hi");
    // Dispatch incoming characters
    while (ss.available() > 0)
      gps.encode(ss.read());




    int head = gps.course.deg();
    int valH = head;
   
 
    //    int sh;
    int sa;
    //sh = 270;
    sa = 1500;

    buttonState = digitalRead(buttonPin);

    long newPosition = myEnc.read();
    if (newPosition != oldPosition) {
      oldPosition = newPosition;
    }
    float sh = newPosition / 4;
    int b = mydata.b;
    //sh = constrain(sh, 0, 360);
    if (sh > 359) {
      myEnc.write(0);
    }
    if (sh < 0) {
      myEnc.write(1436);
    }

    int Sh = sh;
      if (buttonState == LOW) {
        Sh = b;
      delay(50);
      
    }
   
    lcd.setCursor(0, 0);
    lcd.print("CH:");
    lcd.setCursor(3, 0);
    lcd.print(b);
    lcd.print("   ");
   
    lcd.setCursor(9, 0);
    lcd.print("A:");
    lcd.setCursor(11, 0);
    lcd.print(mydata.a);
    lcd.print("     ");

    lcd.setCursor(0, 1);
    lcd.print(">H:");
    lcd.setCursor(3, 1);
    lcd.print(Sh);
    lcd.print("   ");
    lcd.setCursor(6, 1);
    lcd.print("");
    lcd.setCursor(8, 1);
    lcd.print(">A:");
    lcd.setCursor(11, 1);
    lcd.print("1500");
    lcd.print("     ");
    Serial.println(sh, 0);
  }
}
void receive(int numBytes) {}

Use a state change approach for the button, like you do for the encoder update.

I tried something like that but it just displays the "b" value itself which changes (it's magnetic compass heading)

I want it to save and display the value.

b value :

1, 2, 3, 4 (button pressed and released (encoder button)

Sh value= 4

b value: 5, 6, 7 ...etc

Sh value remains 4 until encoder changes position and then Sh becomes the encoder reading.

Button pressed and released again
Sh value becomes the value of what b was at that moment

Why not post the code you tried?

Given the number of different variables you have defined, it looks like you may not have grasped the difference between...
Global variable: declared at the top of your program, retains its set value
Local variable: declared inside a function (e.g. loop), gets reset every time through the function

Putting a type name keyword, “int” “Float” etc, before a variable name declares a new copy of the variable. It replaces any existing variable of the same name.