问:
Reduce The Lengthly Code In Firemonkey
I have many layouts in my Firemonkey APP, and all the TVertscrollBox share the same DoCalcContentsBounds, DoRestorePosition, DoUpdateKBBounds as below, I want to reduce it and keep the same functionality, how can I do?</p>

```<code>    procedure TBTCXCHGForm.BTCXCHGDoRestorePosition;
begin
  if BTCXCHGAddSalesVertScrollBox.Visible then
  begin
    with BTCXCHGAddSalesVertScrollBox do
      ViewportPosition := PointF(ViewportPosition.X, 0);
  end
  else
  begin
    if BTCXCHGEnterSellerDetailVertScrollBox.Visible then
    begin
      with BTCXCHGEnterSellerDetailVertScrollBox do
        ViewportPosition := PointF(ViewportPosition.X, 0);
    end
    else
    begin
      if BTCXCHGEnterBuyBTCDetailVertScrollBox.Visible then
      begin
        with BTCXCHGEnterBuyBTCDetailVertScrollBox do
          ViewportPosition := PointF(ViewportPosition.X, 0);
      end
      else
      begin
        if BTCXCHGAddBuyVertScrollBox.Visible then
        begin
          with BTCXCHGAddBuyVertScrollBox do
            ViewportPosition := PointF(ViewportPosition.X, 0);
        end
        else
        begin
          if BTCXCHGChangeSalesConfirmationVertScrollBox.Visible then
          begin
            with BTCXCHGChangeSalesConfirmationVertScrollBox do
              ViewportPosition := PointF(ViewportPosition.X, 0);
          end
          else
          begin
            if BTCXCHGEnterSellBTCDetailVertScrollBox.Visible then
            begin
              with BTCXCHGEnterSellBTCDetailVertScrollBox do
                ViewportPosition := PointF(ViewportPosition.X, 0);
            end
            else
            begin
              if BTCXCHGMinerPurchaseVertScrollBox.Visible then
              begin
                with BTCXCHGMinerPurchaseVertScrollBox do
                  ViewportPosition := PointF(ViewportPosition.X, 0);
              end
              else
              begin
                if BTCXCHGReceiveBitcoinsVertScrollBox.Visible then
                begin
                  with BTCXCHGReceiveBitcoinsVertScrollBox do
                    ViewportPosition := PointF(ViewportPosition.X, 0);
                end
                else
                begin
                  if BTCXCHGSendBitcoinsVertScrollBox.Visible then
                  begin
                    with BTCXCHGSendBitcoinsVertScrollBox do
                      ViewportPosition := PointF(ViewportPosition.X, 0);
                  end
                  else
                  begin
                    if BTCXCHGUserRegistrationVertScrollBox.Visible then
                    begin
                      with BTCXCHGUserRegistrationVertScrollBox do
                        ViewportPosition := PointF(ViewportPosition.X, 0);
                    end
                    else
                    begin
                      if BTCXCHGChangeSecurityPasswordVertScrollBox.Visible then
                      begin
                        with BTCXCHGChangeSecurityPasswordVertScrollBox do
                          ViewportPosition := PointF(ViewportPosition.X, 0);
                      end
                      else
                      begin
                        if BTCXCHGChangeUserPasswordVertScrollBox.Visible then
                        begin
                          with BTCXCHGChangeUserPasswordVertScrollBox do
                            ViewportPosition := PointF(ViewportPosition.X, 0);
                        end
                        else
                        begin
                          if BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox.Visible then
                          begin
                            with BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox do
                              ViewportPosition := PointF(ViewportPosition.X, 0);
                          end
                          else
                          begin
                            if BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox.Visible then
                            begin
                              with BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox do
                                ViewportPosition := PointF(ViewportPosition.X, 0);
                            end
                            else
                            begin
                              if BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox.Visible then
                              begin
                                with BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox do
                                  ViewportPosition := PointF(ViewportPosition.X, 0);
                              end
                              else
                              begin
                                if BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox.Visible then
                                begin
                                  with BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox do
                                    ViewportPosition := PointF(ViewportPosition.X, 0);
                                end;
                              end;
                            end;
                          end;
                        end;
                      end;
                    end;
                  end;
                end;
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end;

procedure TBTCXCHGForm.BTCXCHGDoUpdateKBBounds;
var
  LFocused: TControl;
  LFocusRect: TRectF;
begin
  if BTCXCHGAddSalesVertScrollBox.Visible then
  begin
      BTCXCHGNeedOffset := False;

      if Assigned(Focused) then
      begin
        LFocused := TControl(Focused.GetObject);
        LFocusRect := LFocused.AbsoluteRect;
        LFocusRect.Offset(BTCXCHGAddSalesVertScrollBox.ViewportPosition);

        if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
        begin
          BTCXCHGNeedOffset := True;
          BTCXCHGAddSalesLayout.Align := TAlignLayout.Horizontal;
          with BTCXCHGAddSalesVertScrollBox do
          begin
            RealignContent;
            Application.ProcessMessages;
            ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
          end;
        end;
      end;

      if not BTCXCHGNeedOffset then
        BTCXCHGDoRestorePosition;
  end
  else
  begin
    if BTCXCHGEnterSellerDetailVertScrollBox.Visible then
    begin
      BTCXCHGNeedOffset := False;

      if Assigned(Focused) then
      begin
        LFocused := TControl(Focused.GetObject);
        LFocusRect := LFocused.AbsoluteRect;
        LFocusRect.Offset(BTCXCHGEnterSellerDetailVertScrollBox.ViewportPosition);

        if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
        begin
          BTCXCHGNeedOffset := True;
          BTCXCHGEnterSellerDetailLayout.Align := TAlignLayout.Horizontal;
          with BTCXCHGEnterSellerDetailVertScrollBox do
          begin
            RealignContent;
            Application.ProcessMessages;
            ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
          end;
        end;
      end;

      if not BTCXCHGNeedOffset then
        BTCXCHGDoRestorePosition;
    end
    else
    begin
      if BTCXCHGEnterBuyBTCDetailVertScrollBox.Visible then
      begin
        BTCXCHGNeedOffset := False;

        if Assigned(Focused) then
        begin
          LFocused := TControl(Focused.GetObject);
          LFocusRect := LFocused.AbsoluteRect;
          LFocusRect.Offset(BTCXCHGEnterBuyBTCDetailVertScrollBox.ViewportPosition);

          if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
          begin
            BTCXCHGNeedOffset := True;
            BTCXCHGEnterBuyBTCDetailLayout.Align := TAlignLayout.Horizontal;
            with BTCXCHGEnterBuyBTCDetailVertScrollBox do
            begin
              RealignContent;
              Application.ProcessMessages;
              ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
            end;
          end;
        end;

        if not BTCXCHGNeedOffset then
          BTCXCHGDoRestorePosition;
      end
      else
      begin
        if BTCXCHGAddBuyVertScrollBox.Visible then
        begin
          BTCXCHGNeedOffset := False;

          if Assigned(Focused) then
          begin
            LFocused := TControl(Focused.GetObject);
            LFocusRect := LFocused.AbsoluteRect;
            LFocusRect.Offset(BTCXCHGAddBuyVertScrollBox.ViewportPosition);

            if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
            begin
              BTCXCHGNeedOffset := True;
              BTCXCHGAddBuyLayout.Align := TAlignLayout.Horizontal;
              with BTCXCHGAddBuyVertScrollBox do
              begin
                RealignContent;
                Application.ProcessMessages;
                ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
              end;
            end;
          end;

          if not BTCXCHGNeedOffset then
            BTCXCHGDoRestorePosition;
        end
        else
        begin
          if BTCXCHGChangeSalesConfirmationVertScrollBox.Visible then
          begin
            BTCXCHGNeedOffset := False;

            if Assigned(Focused) then
            begin
              LFocused := TControl(Focused.GetObject);
              LFocusRect := LFocused.AbsoluteRect;
              LFocusRect.Offset(BTCXCHGChangeSalesConfirmationVertScrollBox.ViewportPosition);

              if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
              begin
                BTCXCHGNeedOffset := True;
                BTCXCHGChangeSalesConfirmationLayout.Align := TAlignLayout.Horizontal;
                with BTCXCHGChangeSalesConfirmationVertScrollBox do
                begin
                  RealignContent;
                  Application.ProcessMessages;
                  ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                end;
              end;
            end;

            if not BTCXCHGNeedOffset then
              BTCXCHGDoRestorePosition;
          end
          else
          begin
            if BTCXCHGEnterSellBTCDetailVertScrollBox.Visible then
            begin
              BTCXCHGNeedOffset := False;

              if Assigned(Focused) then
              begin
                LFocused := TControl(Focused.GetObject);
                LFocusRect := LFocused.AbsoluteRect;
                LFocusRect.Offset(BTCXCHGEnterSellBTCDetailVertScrollBox.ViewportPosition);

                if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                begin
                  BTCXCHGNeedOffset := True;
                  BTCXCHGEnterSellBTCDetailLayout.Align := TAlignLayout.Horizontal;
                  with BTCXCHGEnterSellBTCDetailVertScrollBox do
                  begin
                    RealignContent;
                    Application.ProcessMessages;
                    ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                  end;
                end;
              end;

              if not BTCXCHGNeedOffset then
                BTCXCHGDoRestorePosition;
            end
            else
            begin
              if BTCXCHGMinerPurchaseVertScrollBox.Visible then
              begin
                BTCXCHGNeedOffset := False;

                if Assigned(Focused) then
                begin
                  LFocused := TControl(Focused.GetObject);
                  LFocusRect := LFocused.AbsoluteRect;
                  LFocusRect.Offset(BTCXCHGMinerPurchaseVertScrollBox.ViewportPosition);

                  if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                  begin
                    BTCXCHGNeedOffset := True;
                    BTCXCHGMinerPurchaseLayout.Align := TAlignLayout.Horizontal;
                    with BTCXCHGMinerPurchaseVertScrollBox do
                    begin
                      RealignContent;
                      Application.ProcessMessages;
                      ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                    end;
                  end;
                end;

                if not BTCXCHGNeedOffset then
                  BTCXCHGDoRestorePosition;
              end
              else
              begin
                if BTCXCHGReceiveBitcoinsVertScrollBox.Visible then
                begin
                  BTCXCHGNeedOffset := False;

                  if Assigned(Focused) then
                  begin
                    LFocused := TControl(Focused.GetObject);
                    LFocusRect := LFocused.AbsoluteRect;
                    LFocusRect.Offset(BTCXCHGReceiveBitcoinsVertScrollBox.ViewportPosition);

                    if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                    begin
                      BTCXCHGNeedOffset := True;
                      BTCXCHGReceiveBitcoinsLayout.Align := TAlignLayout.Horizontal;
                      with BTCXCHGReceiveBitcoinsVertScrollBox do
                      begin
                        RealignContent;
                        Application.ProcessMessages;
                        ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                      end;
                    end;
                  end;

                  if not BTCXCHGNeedOffset then
                    BTCXCHGDoRestorePosition;
                end
                else
                begin
                  if BTCXCHGSendBitcoinsVertScrollBox.Visible then
                  begin
                    BTCXCHGNeedOffset := False;

                    if Assigned(Focused) then
                    begin
                      LFocused := TControl(Focused.GetObject);
                      LFocusRect := LFocused.AbsoluteRect;
                      LFocusRect.Offset(BTCXCHGSendBitcoinsVertScrollBox.ViewportPosition);

                      if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                      begin
                        BTCXCHGNeedOffset := True;
                        BTCXCHGSendBitcoinsLayout.Align := TAlignLayout.Horizontal;
                        with BTCXCHGSendBitcoinsVertScrollBox do
                        begin
                          RealignContent;
                          Application.ProcessMessages;
                          ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                        end;
                      end;
                    end;

                    if not BTCXCHGNeedOffset then
                      BTCXCHGDoRestorePosition;
                  end
                  else
                  begin
                    if BTCXCHGUserRegistrationVertScrollBox.Visible then
                    begin
                      BTCXCHGNeedOffset := False;

                      if Assigned(Focused) then
                      begin
                        LFocused := TControl(Focused.GetObject);
                        LFocusRect := LFocused.AbsoluteRect;
                        LFocusRect.Offset(BTCXCHGUserRegistrationVertScrollBox.ViewportPosition);

                        if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                        begin
                          BTCXCHGNeedOffset := True;
                          BTCXCHGUserRegistrationLayout.Align := TAlignLayout.Horizontal;
                          with BTCXCHGUserRegistrationVertScrollBox do
                          begin
                            RealignContent;
                            Application.ProcessMessages;
                            ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                          end;
                        end;
                      end;

                      if not BTCXCHGNeedOffset then
                        BTCXCHGDoRestorePosition;
                    end
                    else
                    begin
                      if BTCXCHGChangeSecurityPasswordVertScrollBox.Visible then
                      begin
                        BTCXCHGNeedOffset := False;

                        if Assigned(Focused) then
                        begin
                          LFocused := TControl(Focused.GetObject);
                          LFocusRect := LFocused.AbsoluteRect;
                          LFocusRect.Offset(BTCXCHGChangeSecurityPasswordVertScrollBox.ViewportPosition);

                          if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                          begin
                            BTCXCHGNeedOffset := True;
                            BTCXCHGChangeSecurityPasswordLayout.Align := TAlignLayout.Horizontal;
                            with BTCXCHGChangeSecurityPasswordVertScrollBox do
                            begin
                              RealignContent;
                              Application.ProcessMessages;
                              ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                            end;
                          end;
                        end;

                        if not BTCXCHGNeedOffset then
                          BTCXCHGDoRestorePosition;
                      end
                      else
                      begin
                        if BTCXCHGChangeUserPasswordVertScrollBox.Visible then
                        begin
                          BTCXCHGNeedOffset := False;

                          if Assigned(Focused) then
                          begin
                            LFocused := TControl(Focused.GetObject);
                            LFocusRect := LFocused.AbsoluteRect;
                            LFocusRect.Offset(BTCXCHGChangeUserPasswordVertScrollBox.ViewportPosition);

                            if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                            begin
                              BTCXCHGNeedOffset := True;
                              BTCXCHGChangeUserPasswordLayout.Align := TAlignLayout.Horizontal;
                              with BTCXCHGChangeUserPasswordVertScrollBox do
                              begin
                                RealignContent;
                                Application.ProcessMessages;
                                ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                              end;
                            end;
                          end;

                          if not BTCXCHGNeedOffset then
                            BTCXCHGDoRestorePosition;
                        end
                        else
                        begin
                          if BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox.Visible then
                          begin
                            BTCXCHGNeedOffset := False;

                            if Assigned(Focused) then
                            begin
                              LFocused := TControl(Focused.GetObject);
                              LFocusRect := LFocused.AbsoluteRect;
                              LFocusRect.Offset(BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox.ViewportPosition);

                              if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                              begin
                                BTCXCHGNeedOffset := True;
                                BTCXCHGLoginRegisterSelectionUserEmailVerificationLayout.Align := TAlignLayout.Horizontal;
                                with BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox do
                                begin
                                  RealignContent;
                                  Application.ProcessMessages;
                                  ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                                end;
                              end;
                            end;

                            if not BTCXCHGNeedOffset then
                              BTCXCHGDoRestorePosition;
                          end
                          else
                          begin
                            if BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox.Visible then
                            begin
                              BTCXCHGNeedOffset := False;

                              if Assigned(Focused) then
                              begin
                                LFocused := TControl(Focused.GetObject);
                                LFocusRect := LFocused.AbsoluteRect;
                                LFocusRect.Offset(BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox.ViewportPosition);

                                if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                                begin
                                  BTCXCHGNeedOffset := True;
                                  BTCXCHGLoginRegisterSelectionUserForgetPasswordLayout.Align := TAlignLayout.Horizontal;
                                  with BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox do
                                  begin
                                    RealignContent;
                                    Application.ProcessMessages;
                                    ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                                  end;
                                end;
                              end;

                              if not BTCXCHGNeedOffset then
                                BTCXCHGDoRestorePosition;
                            end
                            else
                            begin
                              if BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox.Visible then
                              begin
                                BTCXCHGNeedOffset := False;

                                if Assigned(Focused) then
                                begin
                                  LFocused := TControl(Focused.GetObject);
                                  LFocusRect := LFocused.AbsoluteRect;
                                  LFocusRect.Offset(BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox.ViewportPosition);

                                  if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                                  begin
                                    BTCXCHGNeedOffset := True;
                                    BTCXCHGLoginRegisterSelectionUserLoginLayout.Align := TAlignLayout.Horizontal;
                                    with BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox do
                                    begin
                                      RealignContent;
                                      Application.ProcessMessages;
                                      ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                                    end;
                                  end;
                                end;

                                if not BTCXCHGNeedOffset then
                                  BTCXCHGDoRestorePosition;
                              end
                              else
                              begin
                                if BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox.Visible then
                                begin
                                  BTCXCHGNeedOffset := False;

                                  if Assigned(Focused) then
                                  begin
                                    LFocused := TControl(Focused.GetObject);
                                    LFocusRect := LFocused.AbsoluteRect;
                                    LFocusRect.Offset(BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox.ViewportPosition);

                                    if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                                    begin
                                      BTCXCHGNeedOffset := True;
                                      BTCXCHGLoginRegisterSelectionRegistrationLayout.Align := TAlignLayout.Horizontal;
                                      with BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox do
                                      begin
                                        RealignContent;
                                        Application.ProcessMessages;
                                        ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                                      end;
                                    end;
                                  end;

                                  if not BTCXCHGNeedOffset then
                                    BTCXCHGDoRestorePosition;
                                end;
                              end;
                            end;
                          end;
                        end;
                      end;
                    end;
                  end;
                end;
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end;
</code>```

答:
Declare a field in TBTCXCHGForm to hold a reference to currently visible VertScrollBox. Whenever the visible VertScrollBox is changed, assign the scroll box to this field. For example:

```<code>CurrentlyVisibleVertScrollBox: TVertscrollBox;
</code>```

Then your BTCXCHGDoRestorePosition procedure can be reduced to

```<code>procedure TBTCXCHGForm.BTCXCHGDoRestorePosition;
begin
  with CurrentlyVisibleVertScrollBox do  // <----
    ViewportPosition := PointF(ViewportPosition.X, 0);
end;
</code>```

and the BTCXCHGDoUpdateKBBounds can be reduced to

```<code>procedure TBTCXCHGForm.BTCXCHGDoUpdateKBBounds;
var
  LFocused: TControl;
  LFocusRect: TRectF;
begin
  BTCXCHGNeedOffset := False;

  if Assigned(Focused) then
  begin
    LFocused := TControl(Focused.GetObject);
    LFocusRect := LFocused.AbsoluteRect;
    LFocusRect.Offset(CurrentlyVisibleVertScrollBox.ViewportPosition);  // <----

    if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
    begin
      BTCXCHGNeedOffset := True;
      BTCXCHGAddSalesLayout.Align := TAlignLayout.Horizontal;
      with CurrentlyVisibleVertScrollBox do  // <----
      begin
        RealignContent;
        Application.ProcessMessages;
        ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
      end;
    end;
  end;

  if not BTCXCHGNeedOffset then
    BTCXCHGDoRestorePosition;
end;
</code>```

The modified lines are marked (  // <----).
You did not post the third procedure, DoCalcContentsBounds, but if it follows a similar pattern, it should be obvious how to modify it.

Title: Reduce The Lengthly Code In Firemonkey

Body:
I have many layouts in my Firemonkey APP, and all the TVertscrollBox share the same DoCalcContentsBounds, DoRestorePosition, DoUpdateKBBounds as below, I want to reduce it and keep the same functionality, how can I do?

    procedure TBTCXCHGForm.BTCXCHGDoRestorePosition;
begin
  if BTCXCHGAddSalesVertScrollBox.Visible then
  begin
    with BTCXCHGAddSalesVertScrollBox do
      ViewportPosition := PointF(ViewportPosition.X, 0);
  end
  else
  begin
    if BTCXCHGEnterSellerDetailVertScrollBox.Visible then
    begin
      with BTCXCHGEnterSellerDetailVertScrollBox do
        ViewportPosition := PointF(ViewportPosition.X, 0);
    end
    else
    begin
      if BTCXCHGEnterBuyBTCDetailVertScrollBox.Visible then
      begin
        with BTCXCHGEnterBuyBTCDetailVertScrollBox do
          ViewportPosition := PointF(ViewportPosition.X, 0);
      end
      else
      begin
        if BTCXCHGAddBuyVertScrollBox.Visible then
        begin
          with BTCXCHGAddBuyVertScrollBox do
            ViewportPosition := PointF(ViewportPosition.X, 0);
        end
        else
        begin
          if BTCXCHGChangeSalesConfirmationVertScrollBox.Visible then
          begin
            with BTCXCHGChangeSalesConfirmationVertScrollBox do
              ViewportPosition := PointF(ViewportPosition.X, 0);
          end
          else
          begin
            if BTCXCHGEnterSellBTCDetailVertScrollBox.Visible then
            begin
              with BTCXCHGEnterSellBTCDetailVertScrollBox do
                ViewportPosition := PointF(ViewportPosition.X, 0);
            end
            else
            begin
              if BTCXCHGMinerPurchaseVertScrollBox.Visible then
              begin
                with BTCXCHGMinerPurchaseVertScrollBox do
                  ViewportPosition := PointF(ViewportPosition.X, 0);
              end
              else
              begin
                if BTCXCHGReceiveBitcoinsVertScrollBox.Visible then
                begin
                  with BTCXCHGReceiveBitcoinsVertScrollBox do
                    ViewportPosition := PointF(ViewportPosition.X, 0);
                end
                else
                begin
                  if BTCXCHGSendBitcoinsVertScrollBox.Visible then
                  begin
                    with BTCXCHGSendBitcoinsVertScrollBox do
                      ViewportPosition := PointF(ViewportPosition.X, 0);
                  end
                  else
                  begin
                    if BTCXCHGUserRegistrationVertScrollBox.Visible then
                    begin
                      with BTCXCHGUserRegistrationVertScrollBox do
                        ViewportPosition := PointF(ViewportPosition.X, 0);
                    end
                    else
                    begin
                      if BTCXCHGChangeSecurityPasswordVertScrollBox.Visible then
                      begin
                        with BTCXCHGChangeSecurityPasswordVertScrollBox do
                          ViewportPosition := PointF(ViewportPosition.X, 0);
                      end
                      else
                      begin
                        if BTCXCHGChangeUserPasswordVertScrollBox.Visible then
                        begin
                          with BTCXCHGChangeUserPasswordVertScrollBox do
                            ViewportPosition := PointF(ViewportPosition.X, 0);
                        end
                        else
                        begin
                          if BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox.Visible then
                          begin
                            with BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox do
                              ViewportPosition := PointF(ViewportPosition.X, 0);
                          end
                          else
                          begin
                            if BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox.Visible then
                            begin
                              with BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox do
                                ViewportPosition := PointF(ViewportPosition.X, 0);
                            end
                            else
                            begin
                              if BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox.Visible then
                              begin
                                with BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox do
                                  ViewportPosition := PointF(ViewportPosition.X, 0);
                              end
                              else
                              begin
                                if BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox.Visible then
                                begin
                                  with BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox do
                                    ViewportPosition := PointF(ViewportPosition.X, 0);
                                end;
                              end;
                            end;
                          end;
                        end;
                      end;
                    end;
                  end;
                end;
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end;

procedure TBTCXCHGForm.BTCXCHGDoUpdateKBBounds;
var
  LFocused: TControl;
  LFocusRect: TRectF;
begin
  if BTCXCHGAddSalesVertScrollBox.Visible then
  begin
      BTCXCHGNeedOffset := False;

      if Assigned(Focused) then
      begin
        LFocused := TControl(Focused.GetObject);
        LFocusRect := LFocused.AbsoluteRect;
        LFocusRect.Offset(BTCXCHGAddSalesVertScrollBox.ViewportPosition);

        if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
        begin
          BTCXCHGNeedOffset := True;
          BTCXCHGAddSalesLayout.Align := TAlignLayout.Horizontal;
          with BTCXCHGAddSalesVertScrollBox do
          begin
            RealignContent;
            Application.ProcessMessages;
            ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
          end;
        end;
      end;

      if not BTCXCHGNeedOffset then
        BTCXCHGDoRestorePosition;
  end
  else
  begin
    if BTCXCHGEnterSellerDetailVertScrollBox.Visible then
    begin
      BTCXCHGNeedOffset := False;

      if Assigned(Focused) then
      begin
        LFocused := TControl(Focused.GetObject);
        LFocusRect := LFocused.AbsoluteRect;
        LFocusRect.Offset(BTCXCHGEnterSellerDetailVertScrollBox.ViewportPosition);

        if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
        begin
          BTCXCHGNeedOffset := True;
          BTCXCHGEnterSellerDetailLayout.Align := TAlignLayout.Horizontal;
          with BTCXCHGEnterSellerDetailVertScrollBox do
          begin
            RealignContent;
            Application.ProcessMessages;
            ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
          end;
        end;
      end;

      if not BTCXCHGNeedOffset then
        BTCXCHGDoRestorePosition;
    end
    else
    begin
      if BTCXCHGEnterBuyBTCDetailVertScrollBox.Visible then
      begin
        BTCXCHGNeedOffset := False;

        if Assigned(Focused) then
        begin
          LFocused := TControl(Focused.GetObject);
          LFocusRect := LFocused.AbsoluteRect;
          LFocusRect.Offset(BTCXCHGEnterBuyBTCDetailVertScrollBox.ViewportPosition);

          if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
          begin
            BTCXCHGNeedOffset := True;
            BTCXCHGEnterBuyBTCDetailLayout.Align := TAlignLayout.Horizontal;
            with BTCXCHGEnterBuyBTCDetailVertScrollBox do
            begin
              RealignContent;
              Application.ProcessMessages;
              ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
            end;
          end;
        end;

        if not BTCXCHGNeedOffset then
          BTCXCHGDoRestorePosition;
      end
      else
      begin
        if BTCXCHGAddBuyVertScrollBox.Visible then
        begin
          BTCXCHGNeedOffset := False;

          if Assigned(Focused) then
          begin
            LFocused := TControl(Focused.GetObject);
            LFocusRect := LFocused.AbsoluteRect;
            LFocusRect.Offset(BTCXCHGAddBuyVertScrollBox.ViewportPosition);

            if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
            begin
              BTCXCHGNeedOffset := True;
              BTCXCHGAddBuyLayout.Align := TAlignLayout.Horizontal;
              with BTCXCHGAddBuyVertScrollBox do
              begin
                RealignContent;
                Application.ProcessMessages;
                ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
              end;
            end;
          end;

          if not BTCXCHGNeedOffset then
            BTCXCHGDoRestorePosition;
        end
        else
        begin
          if BTCXCHGChangeSalesConfirmationVertScrollBox.Visible then
          begin
            BTCXCHGNeedOffset := False;

            if Assigned(Focused) then
            begin
              LFocused := TControl(Focused.GetObject);
              LFocusRect := LFocused.AbsoluteRect;
              LFocusRect.Offset(BTCXCHGChangeSalesConfirmationVertScrollBox.ViewportPosition);

              if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
              begin
                BTCXCHGNeedOffset := True;
                BTCXCHGChangeSalesConfirmationLayout.Align := TAlignLayout.Horizontal;
                with BTCXCHGChangeSalesConfirmationVertScrollBox do
                begin
                  RealignContent;
                  Application.ProcessMessages;
                  ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                end;
              end;
            end;

            if not BTCXCHGNeedOffset then
              BTCXCHGDoRestorePosition;
          end
          else
          begin
            if BTCXCHGEnterSellBTCDetailVertScrollBox.Visible then
            begin
              BTCXCHGNeedOffset := False;

              if Assigned(Focused) then
              begin
                LFocused := TControl(Focused.GetObject);
                LFocusRect := LFocused.AbsoluteRect;
                LFocusRect.Offset(BTCXCHGEnterSellBTCDetailVertScrollBox.ViewportPosition);

                if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                begin
                  BTCXCHGNeedOffset := True;
                  BTCXCHGEnterSellBTCDetailLayout.Align := TAlignLayout.Horizontal;
                  with BTCXCHGEnterSellBTCDetailVertScrollBox do
                  begin
                    RealignContent;
                    Application.ProcessMessages;
                    ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                  end;
                end;
              end;

              if not BTCXCHGNeedOffset then
                BTCXCHGDoRestorePosition;
            end
            else
            begin
              if BTCXCHGMinerPurchaseVertScrollBox.Visible then
              begin
                BTCXCHGNeedOffset := False;

                if Assigned(Focused) then
                begin
                  LFocused := TControl(Focused.GetObject);
                  LFocusRect := LFocused.AbsoluteRect;
                  LFocusRect.Offset(BTCXCHGMinerPurchaseVertScrollBox.ViewportPosition);

                  if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                  begin
                    BTCXCHGNeedOffset := True;
                    BTCXCHGMinerPurchaseLayout.Align := TAlignLayout.Horizontal;
                    with BTCXCHGMinerPurchaseVertScrollBox do
                    begin
                      RealignContent;
                      Application.ProcessMessages;
                      ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                    end;
                  end;
                end;

                if not BTCXCHGNeedOffset then
                  BTCXCHGDoRestorePosition;
              end
              else
              begin
                if BTCXCHGReceiveBitcoinsVertScrollBox.Visible then
                begin
                  BTCXCHGNeedOffset := False;

                  if Assigned(Focused) then
                  begin
                    LFocused := TControl(Focused.GetObject);
                    LFocusRect := LFocused.AbsoluteRect;
                    LFocusRect.Offset(BTCXCHGReceiveBitcoinsVertScrollBox.ViewportPosition);

                    if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                    begin
                      BTCXCHGNeedOffset := True;
                      BTCXCHGReceiveBitcoinsLayout.Align := TAlignLayout.Horizontal;
                      with BTCXCHGReceiveBitcoinsVertScrollBox do
                      begin
                        RealignContent;
                        Application.ProcessMessages;
                        ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                      end;
                    end;
                  end;

                  if not BTCXCHGNeedOffset then
                    BTCXCHGDoRestorePosition;
                end
                else
                begin
                  if BTCXCHGSendBitcoinsVertScrollBox.Visible then
                  begin
                    BTCXCHGNeedOffset := False;

                    if Assigned(Focused) then
                    begin
                      LFocused := TControl(Focused.GetObject);
                      LFocusRect := LFocused.AbsoluteRect;
                      LFocusRect.Offset(BTCXCHGSendBitcoinsVertScrollBox.ViewportPosition);

                      if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                      begin
                        BTCXCHGNeedOffset := True;
                        BTCXCHGSendBitcoinsLayout.Align := TAlignLayout.Horizontal;
                        with BTCXCHGSendBitcoinsVertScrollBox do
                        begin
                          RealignContent;
                          Application.ProcessMessages;
                          ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                        end;
                      end;
                    end;

                    if not BTCXCHGNeedOffset then
                      BTCXCHGDoRestorePosition;
                  end
                  else
                  begin
                    if BTCXCHGUserRegistrationVertScrollBox.Visible then
                    begin
                      BTCXCHGNeedOffset := False;

                      if Assigned(Focused) then
                      begin
                        LFocused := TControl(Focused.GetObject);
                        LFocusRect := LFocused.AbsoluteRect;
                        LFocusRect.Offset(BTCXCHGUserRegistrationVertScrollBox.ViewportPosition);

                        if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                        begin
                          BTCXCHGNeedOffset := True;
                          BTCXCHGUserRegistrationLayout.Align := TAlignLayout.Horizontal;
                          with BTCXCHGUserRegistrationVertScrollBox do
                          begin
                            RealignContent;
                            Application.ProcessMessages;
                            ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                          end;
                        end;
                      end;

                      if not BTCXCHGNeedOffset then
                        BTCXCHGDoRestorePosition;
                    end
                    else
                    begin
                      if BTCXCHGChangeSecurityPasswordVertScrollBox.Visible then
                      begin
                        BTCXCHGNeedOffset := False;

                        if Assigned(Focused) then
                        begin
                          LFocused := TControl(Focused.GetObject);
                          LFocusRect := LFocused.AbsoluteRect;
                          LFocusRect.Offset(BTCXCHGChangeSecurityPasswordVertScrollBox.ViewportPosition);

                          if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                          begin
                            BTCXCHGNeedOffset := True;
                            BTCXCHGChangeSecurityPasswordLayout.Align := TAlignLayout.Horizontal;
                            with BTCXCHGChangeSecurityPasswordVertScrollBox do
                            begin
                              RealignContent;
                              Application.ProcessMessages;
                              ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                            end;
                          end;
                        end;

                        if not BTCXCHGNeedOffset then
                          BTCXCHGDoRestorePosition;
                      end
                      else
                      begin
                        if BTCXCHGChangeUserPasswordVertScrollBox.Visible then
                        begin
                          BTCXCHGNeedOffset := False;

                          if Assigned(Focused) then
                          begin
                            LFocused := TControl(Focused.GetObject);
                            LFocusRect := LFocused.AbsoluteRect;
                            LFocusRect.Offset(BTCXCHGChangeUserPasswordVertScrollBox.ViewportPosition);

                            if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                            begin
                              BTCXCHGNeedOffset := True;
                              BTCXCHGChangeUserPasswordLayout.Align := TAlignLayout.Horizontal;
                              with BTCXCHGChangeUserPasswordVertScrollBox do
                              begin
                                RealignContent;
                                Application.ProcessMessages;
                                ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                              end;
                            end;
                          end;

                          if not BTCXCHGNeedOffset then
                            BTCXCHGDoRestorePosition;
                        end
                        else
                        begin
                          if BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox.Visible then
                          begin
                            BTCXCHGNeedOffset := False;

                            if Assigned(Focused) then
                            begin
                              LFocused := TControl(Focused.GetObject);
                              LFocusRect := LFocused.AbsoluteRect;
                              LFocusRect.Offset(BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox.ViewportPosition);

                              if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                              begin
                                BTCXCHGNeedOffset := True;
                                BTCXCHGLoginRegisterSelectionUserEmailVerificationLayout.Align := TAlignLayout.Horizontal;
                                with BTCXCHGLoginRegisterSelectionUserEmailVerificationVertScrollBox do
                                begin
                                  RealignContent;
                                  Application.ProcessMessages;
                                  ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                                end;
                              end;
                            end;

                            if not BTCXCHGNeedOffset then
                              BTCXCHGDoRestorePosition;
                          end
                          else
                          begin
                            if BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox.Visible then
                            begin
                              BTCXCHGNeedOffset := False;

                              if Assigned(Focused) then
                              begin
                                LFocused := TControl(Focused.GetObject);
                                LFocusRect := LFocused.AbsoluteRect;
                                LFocusRect.Offset(BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox.ViewportPosition);

                                if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                                begin
                                  BTCXCHGNeedOffset := True;
                                  BTCXCHGLoginRegisterSelectionUserForgetPasswordLayout.Align := TAlignLayout.Horizontal;
                                  with BTCXCHGLoginRegisterSelectionUserForgetPasswordVertScrollBox do
                                  begin
                                    RealignContent;
                                    Application.ProcessMessages;
                                    ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                                  end;
                                end;
                              end;

                              if not BTCXCHGNeedOffset then
                                BTCXCHGDoRestorePosition;
                            end
                            else
                            begin
                              if BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox.Visible then
                              begin
                                BTCXCHGNeedOffset := False;

                                if Assigned(Focused) then
                                begin
                                  LFocused := TControl(Focused.GetObject);
                                  LFocusRect := LFocused.AbsoluteRect;
                                  LFocusRect.Offset(BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox.ViewportPosition);

                                  if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                                  begin
                                    BTCXCHGNeedOffset := True;
                                    BTCXCHGLoginRegisterSelectionUserLoginLayout.Align := TAlignLayout.Horizontal;
                                    with BTCXCHGLoginRegisterSelectionUserLoginVertScrollBox do
                                    begin
                                      RealignContent;
                                      Application.ProcessMessages;
                                      ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                                    end;
                                  end;
                                end;

                                if not BTCXCHGNeedOffset then
                                  BTCXCHGDoRestorePosition;
                              end
                              else
                              begin
                                if BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox.Visible then
                                begin
                                  BTCXCHGNeedOffset := False;

                                  if Assigned(Focused) then
                                  begin
                                    LFocused := TControl(Focused.GetObject);
                                    LFocusRect := LFocused.AbsoluteRect;
                                    LFocusRect.Offset(BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox.ViewportPosition);

                                    if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
                                    begin
                                      BTCXCHGNeedOffset := True;
                                      BTCXCHGLoginRegisterSelectionRegistrationLayout.Align := TAlignLayout.Horizontal;
                                      with BTCXCHGLoginRegisterSelectionRegistrationVertScrollBox do
                                      begin
                                        RealignContent;
                                        Application.ProcessMessages;
                                        ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
                                      end;
                                    end;
                                  end;

                                  if not BTCXCHGNeedOffset then
                                    BTCXCHGDoRestorePosition;
                                end;
                              end;
                            end;
                          end;
                        end;
                      end;
                    end;
                  end;
                end;
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end;

Body:
Declare a field in TBTCXCHGForm to hold a reference to currently visible VertScrollBox. Whenever the visible VertScrollBox is changed, assign the scroll box to this field. For example:

CurrentlyVisibleVertScrollBox: TVertscrollBox;

Then your BTCXCHGDoRestorePosition procedure can be reduced to

procedure TBTCXCHGForm.BTCXCHGDoRestorePosition;
begin
  with CurrentlyVisibleVertScrollBox do  // <----
    ViewportPosition := PointF(ViewportPosition.X, 0);
end;

and the BTCXCHGDoUpdateKBBounds can be reduced to

procedure TBTCXCHGForm.BTCXCHGDoUpdateKBBounds;
var
  LFocused: TControl;
  LFocusRect: TRectF;
begin
  BTCXCHGNeedOffset := False;

  if Assigned(Focused) then
  begin
    LFocused := TControl(Focused.GetObject);
    LFocusRect := LFocused.AbsoluteRect;
    LFocusRect.Offset(CurrentlyVisibleVertScrollBox.ViewportPosition);  // <----

    if (LFocusRect.IntersectsWith(TRectF.Create(BTCXCHGKBBounds))) and (LFocusRect.Bottom > BTCXCHGKBBounds.Top) then
    begin
      BTCXCHGNeedOffset := True;
      BTCXCHGAddSalesLayout.Align := TAlignLayout.Horizontal;
      with CurrentlyVisibleVertScrollBox do  // <----
      begin
        RealignContent;
        Application.ProcessMessages;
        ViewportPosition := PointF(ViewportPosition.X, LFocusRect.Bottom - BTCXCHGKBBounds.Top);
      end;
    end;
  end;

  if not BTCXCHGNeedOffset then
    BTCXCHGDoRestorePosition;
end;

The modified lines are marked (  // <----).
You did not post the third procedure, DoCalcContentsBounds, but if it follows a similar pattern, it should be obvious how to modify it.


来源: stackexchange

问:
Sending variables from two different HTML sources to a single PHP script using HTML/PHP/JScript only
I have a situation in which a page is built off two different sources with HTML by combining with each other in a containter third page. Each section also has a variable they pass through a form using POST to a single PHP file. These variables change in every execution (When they form a page together).

For example:

```<code><!--Start of HTML 3 -->
<html>
<!-- Start of HTML 1 -->
<body>

<a href='process.php' id='php1' name='php1' onclick='document.getElementById("infoForm").submit()'> A link to php file that receives a hidden form's value</a>

<form id='infoForm' action='process.php' method='POST'>
  <input name ="var1" id="var1" value="changing1" hidden />
</form>
<p>Stuff here</p>
<!-- End of HTML 1 -->

<!-- Start of HTML 2 -->
<p>Some more stuff here</p>
<form id='infoForm2' action='process.php' method='POST'>
  <input name ="var2" id="var2" value="changing2" hidden />
</form>

</body>
<!-- End of HTML 2 -->
</html>
<!-- End of HTML 3 -->
</code>```

A few more details:

The forms are independent of each other, joining them would be difficult since they are created using previous processes that work with other variables.

Code can be added inside HTML 1 and 2, but not 3.

This one will only be able to send var1 to process.php (which can invoke it with $_POST). How could I submit both variables to a single PHP file, using a single link, using basic technologies (e.g. Excluding JQuery, AJAX, etc)? Is there a better way than using forms/POST without using the URI?

EDIT: The method I used was @glenn ferns first point: use the form attribute to attach the second one to the first form in the html makeup:

```<code><!-- Start of HTML 2 -->
<p>Some more stuff here</p>

<input form="infoForm" name ="var2" id="var2" value="changing2" hidden />

</body>
<!-- End of HTML 2 -->
</code>```

答:
3 ways i can think of doing this

-use the form attribute for the input tag in html2 .
https://www.w3schools.com/tags/att_form.asp

-As long as HTML1 and HTML2 are not used independently then you can just open the form in html1 and close it in html 2
Your IDE will probably throw errors, but it should work

-Using js to get the values and submitting the form from the javascript

ContentLicense: CC BY-SA 3.0

Body:
I have a situation in which a page is built off two different sources with HTML by combining with each other in a containter third page. Each section also has a variable they pass through a form using POST to a single PHP file. These variables change in every execution (When they form a page together).

For example:

 A link to php file that receives a hidden form's value

<form id='infoForm' action='process.php' method='POST'>
  <input name ="var1" id="var1" value="changing1" hidden />
</form>

Stuff here

Some more stuff here

<form id='infoForm2' action='process.php' method='POST'>
  <input name ="var2" id="var2" value="changing2" hidden />
</form>

A few more details:

The forms are independent of each other, joining them would be difficult since they are created using previous processes that work with other variables.

Code can be added inside HTML 1 and 2, but not 3.

This one will only be able to send var1 to process.php (which can invoke it with $_POST). How could I submit both variables to a single PHP file, using a single link, using basic technologies (e.g. Excluding JQuery, AJAX, etc)? Is there a better way than using forms/POST without using the URI?

EDIT: The method I used was @glenn ferns first point: use the form attribute to attach the second one to the first form in the html makeup:

Some more stuff here

<input form="infoForm" name ="var2" id="var2" value="changing2" hidden />


问:
Can't get distutils working
I've written a Python script that uses a package that I've created. I need to package it, so I can install it on several servers, but I can't get setup.py to find my scripts.

There's two parts to my script: connections.py and a module that is imported as X.utils.printing (where X is my group name).
I need to bundle both with distutils.

I've read the Python Distutils documentation about five times, and I just don't get it.

Here's what I need to do:
1) Make sure that my printing module is installed and can be imported with

```<code>from X.utils.printing import PrettyPrint as PP
</code>```

2) Put connections.py in /usr/sbin/

This should be very straightforward, but it's become maddening.

Here's my current setup.py that doesn't work:

```<code>from distutils.core import setup

setup(name='connections', version='0.1.1',
      description='Print number of IHS connections',
      author='fandingo', author_email='fandingo@fandingo.com',
      package_dir = {'X.utils' : 'X'},
      packages=['X.utils.printing'], py_modules=['printing', 'connections'])
</code>```

setup.py resides and is run from a directory called 'python' and has connection-stats/ and X inside. connection-stats has connections.py inside. X has init.py, utils/init.py, and utils/printing.py.

When I try to run setup.py, I get the following output:

python setup.py bdist

running bdist running bdist_dumb

running build running build_py file

printing.py (for module printing) not

found file connections.py (for module

connections) not found error: package

directory 'X/printing' does not exist

Could someone help me fix my setup.py, so I can package my script and module?

Thanks for all the help.

Edit: I haven't made any attempt to copy connections.py to /usr/sbin/. I haven't gotten beyond distutils not finding my modules.

Edit 2:
I think that I'm getting much closer, but I can't get my package hierarchy to work.

Using,

```<code>setup(name='connections', version='0.1.1', description='Print number of IHS connections',
      author='fandingo', author_email='fandingo@fanding.com',
      package_dir = {'printing' : 'X/utils'}, packages=['printing'],
      scripts=['connection-stats/connections.py'])
</code>```

I get a successful build that has connections.py in what should become /usr/sbin/ when an installation is performed.
The only problem is that printing gets imported without the X.utils.printing.

I can change it to include X, but it doesn't include child packages.

```<code>setup(name='connections', version='0.1.1',
      description='Print number of IHS connections',
      author='fandingo',
      author_email='fandingo@fandingo.com',
      packages=['X'],
      scripts=['connection-stats/connections.py'])
</code>```

The problem here is that X is imported, but only the init.py. utils/ isn't included, which means I don't get utils/printing.py

It's like I need some sort of recursive option, so I can add X and everything below it. Any thoughts?

Thanks,

----------------------

Edit 3:

Just about completed. I figured out that I need to explicitly list every sub-package in X. Here's the corrected setup.py

```<code>setup(
    name='connections',
    version='0.1.1',
    description='Print number of IHS connections',
    author='fandingo',
    author_email='fandingo@fandingo.com',
    package_dir = {'utils' : 'X/', 'printing' : 'X/utils/'},
    packages=['X', 'X.utils'],
    py_modules = ['printing'],
    scripts=['connection-stats/connections.py'])
</code>```

The only other thing is that connections.py isn't moved to /usr/sbin/. I think that I will just add a post-install option to manually move it.

答:
I think you'll want something like the following:

```<code>from distutils.core import setup

setup(name='connections',
      version='0.1.1',
      description='Print number of IHS connections',
      author='fandingo',
      author_email='fandingo@fandingo.com',
      packages=['X'],
      scripts=['connection-stats/connections.py'])
</code>```

UPDATE: fix packages list

Title: Can't get distutils working

Body:
I've written a Python script that uses a package that I've created. I need to package it, so I can install it on several servers, but I can't get setup.py to find my scripts.

There's two parts to my script: connections.py and a module that is imported as X.utils.printing (where X is my group name).
I need to bundle both with distutils.

I've read the Python Distutils documentation about five times, and I just don't get it.

Here's what I need to do:
1) Make sure that my printing module is installed and can be imported with

from X.utils.printing import PrettyPrint as PP

2) Put connections.py in /usr/sbin/

This should be very straightforward, but it's become maddening.

Here's my current setup.py that doesn't work:

from distutils.core import setup

setup(name='connections', version='0.1.1',
      description='Print number of IHS connections',
      author='fandingo', author_email='fandingo@fandingo.com',
      package_dir = {'X.utils' : 'X'},
      packages=['X.utils.printing'], py_modules=['printing', 'connections'])

setup.py resides and is run from a directory called 'python' and has connection-stats/ and X inside. connection-stats has connections.py inside. X has init.py, utils/init.py, and utils/printing.py.

When I try to run setup.py, I get the following output:

python setup.py bdist

running bdist running bdist_dumb

running build running build_py file

printing.py (for module printing) not

found file connections.py (for module

connections) not found error: package

directory 'X/printing' does not exist

Could someone help me fix my setup.py, so I can package my script and module?

Thanks for all the help.

Edit: I haven't made any attempt to copy connections.py to /usr/sbin/. I haven't gotten beyond distutils not finding my modules.

Edit 2:
I think that I'm getting much closer, but I can't get my package hierarchy to work.

Using,

setup(name='connections', version='0.1.1', description='Print number of IHS connections',
      author='fandingo', author_email='fandingo@fanding.com',
      package_dir = {'printing' : 'X/utils'}, packages=['printing'],
      scripts=['connection-stats/connections.py'])

I get a successful build that has connections.py in what should become /usr/sbin/ when an installation is performed.
The only problem is that printing gets imported without the X.utils.printing.

I can change it to include X, but it doesn't include child packages.

setup(name='connections', version='0.1.1',
      description='Print number of IHS connections',
      author='fandingo',
      author_email='fandingo@fandingo.com',
      packages=['X'],
      scripts=['connection-stats/connections.py'])

The problem here is that X is imported, but only the init.py. utils/ isn't included, which means I don't get utils/printing.py

It's like I need some sort of recursive option, so I can add X and everything below it. Any thoughts?

Thanks,

----------------------

Edit 3:

Just about completed. I figured out that I need to explicitly list every sub-package in X. Here's the corrected setup.py

setup(
    name='connections',
    version='0.1.1',
    description='Print number of IHS connections',
    author='fandingo',
    author_email='fandingo@fandingo.com',
    package_dir = {'utils' : 'X/', 'printing' : 'X/utils/'},
    packages=['X', 'X.utils'],
    py_modules = ['printing'],
    scripts=['connection-stats/connections.py'])

The only other thing is that connections.py isn't moved to /usr/sbin/. I think that I will just add a post-install option to manually move it.

Body:
I think you'll want something like the following:

from distutils.core import setup

setup(name='connections',
      version='0.1.1',
      description='Print number of IHS connections',
      author='fandingo',
      author_email='fandingo@fandingo.com',
      packages=['X'],
      scripts=['connection-stats/connections.py'])

UPDATE: fix packages list

ContentLicense: CC BY-SA 2.5


问:
Pass in any number of arguments into a Javascript function
I want to be able to pass in any number of arguments into a function and then be able to use those arguments later. I know I can pass in default arguments but I don't know what to declare in my function.

For example,

```<code>function test(????) {
  console.log(a)
  console.log(b)
  console.log(c)
}

test(a="a", b="b", c="c")
</code>```

I'm also challenged by being given this function and to make as little changes to the var declarations as much as possible. So here, variables, a, b, and c are declared and I'm not able to edit these variables. I should be able to pass in arguments that will then know to assign itself to these variables.

```<code>function test(???) {
  var a,b,c
  if (a>b){
    c = a + b
  }
}

test(a=2,b=3)
</code>```

答:
```<code>function test(input) {
  console.log(input.a);
  console.log(input.b);
  console.log(input.c);
}

test({ a: 1, b: 2, c: 3 });
</code>```

Body:
I want to be able to pass in any number of arguments into a function and then be able to use those arguments later. I know I can pass in default arguments but I don't know what to declare in my function.

For example,

function test(????) {
  console.log(a)
  console.log(b)
  console.log(c)
}

test(a="a", b="b", c="c")

I'm also challenged by being given this function and to make as little changes to the var declarations as much as possible. So here, variables, a, b, and c are declared and I'm not able to edit these variables. I should be able to pass in arguments that will then know to assign itself to these variables.

function test(???) {
  var a,b,c
  if (a>b){
    c = a + b
  }
}

test(a=2,b=3)


问:
Android ACTION_IMAGE_CAPTURE Intent
We are trying to use the native camera app to let the user take a new picture. It works just fine if we leave out the EXTRA_OUTPUT extra and returns the small Bitmap image. However, if we putExtra(EXTRA_OUTPUT,...) on the intent before starting it, everything works until you try to hit the "Ok" button in the camera app. The "Ok" button just does nothing. The camera app stays open and nothing locks up. We can cancel out of it, but the file never gets written. What exactly do we have to do to get ACTION_IMAGE_CAPTURE to write the picture taken to a file?

Edit: This is done via the MediaStore.ACTION_IMAGE_CAPTURE intent, just to be clear

答:
To follow up on Yenchi's comment above, the OK button will also do nothing if the camera app can't write to the directory in question.

That means that you can't create the file in a place that's only writeable by your application (for instance, something under getCacheDir()) Something under getExternalFilesDir() ought to work, however.

It would be nice if the camera app printed an error message to the logs if it could not write to the specified EXTRA_OUTPUT path, but I didn't find one.

Title: Android ACTION_IMAGE_CAPTURE Intent


问:
How do I calculate the percentage of a value in a column based on constraints on it , in sql?
I was wondering how to calculate the percentage of a certain value based on constraints on it

For instance, let's say I have a hypothetical table called Cats. I insert the following values into it:

```<code>Create table Cats (Cat_ID int, Cat_name varchar(max), Cat_Hometown varchar(max), Gender varchar(max), Birth_Year int);

INSERT INTO Cats (Cat_ID, Cat_Name, Cat_Hometown, Gender, Birth_year)
VALUES (1, 'Blue','Boston','M', 1980),
(2, 'Steamer','Plymouth','F', 1999),
(3, 'Stack','Newton','F', 1980),
(4, 'Overflow','Boston','M', 1978),
(5, 'CatorDog','Allston','F', 1999);
</code>```

What if I want to determine the percentage of the female cats that were born in the leading hometown of the year 1980? I can't seem to figure it out.
By leading hometown I mean the most common hometown.

答:
Assuming leading hometown means the most number of rows in the table for a given year, you can order by the count and get the most common one. Then use conditional aggregation to get the percentage. AVG(gender='F') uses the fact that MySQL treats conditions as booleans returning 1 for True and 0 for False.

```<code>select AVG(gender='F')
from cats
where birth_year=1980  and
cat_hometown in (select cat_hometown
                 from cats
                 where birth_year=1980
                 group by cat_hometown
                 order by count(*) desc
                 limit 1)
</code>```

Body:
I was wondering how to calculate the percentage of a certain value based on constraints on it

For instance, let's say I have a hypothetical table called Cats. I insert the following values into it:

Create table Cats (Cat_ID int, Cat_name varchar(max), Cat_Hometown varchar(max), Gender varchar(max), Birth_Year int);

INSERT INTO Cats (Cat_ID, Cat_Name, Cat_Hometown, Gender, Birth_year)
VALUES (1, 'Blue','Boston','M', 1980),
(2, 'Steamer','Plymouth','F', 1999),
(3, 'Stack','Newton','F', 1980),
(4, 'Overflow','Boston','M', 1978),
(5, 'CatorDog','Allston','F', 1999);

What if I want to determine the percentage of the female cats that were born in the leading hometown of the year 1980? I can't seem to figure it out.
By leading hometown I mean the most common hometown.

Body:
Assuming leading hometown means the most number of rows in the table for a given year, you can order by the count and get the most common one. Then use conditional aggregation to get the percentage. AVG(gender='F') uses the fact that MySQL treats conditions as booleans returning 1 for True and 0 for False.

select AVG(gender='F')
from cats
where birth_year=1980  and
cat_hometown in (select cat_hometown
                 from cats
                 where birth_year=1980
                 group by cat_hometown
                 order by count(*) desc
                 limit 1)


问:
Create simple display
Sorry for this simple question but I don't really understand how correctly create consol on C. I wanna have several dynamic lines that will be update. I know that I can use \r but it is only for one line. I want for several lines. system("cls") not working good for this. Maybe you can help me.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main() {
    int currInt = 0;

    while (true) {
        system("cls");

        printf("%d", currInt);

        currInt++;

        if (currInt == 5) {
            currInt = 0;
        }
    }
}
```

I will be have asynchronous input data that will be display on several lines and I need have update this screen. I think about system("cls") but it not clear screen in loop. Endless loop is important.

答:
I doubt it that printf() will help you achieve your goals. If I were you, I would give a shot with Ncurses. Check this question too: Where can I find a complete reference of the ncurses C API?

If this library won't satisfy you, then I would suggest curses.h. However I doubt this will do, since Ncurses is a modern implementation of the original curses.

For Windows: Is ncurses available for windows?

Title: Create simple display

Body:
Sorry for this simple question but I don't really understand how correctly create consol on C. I wanna have several dynamic lines that will be update. I know that I can use \r but it is only for one line. I want for several lines. system("cls") not working good for this. Maybe you can help me.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main() {
    int currInt = 0;

    while (true) {
        system("cls");

        printf("%d", currInt);

        currInt++;

        if (currInt == 5) {
            currInt = 0;
        }
    }
}

I will be have asynchronous input data that will be display on several lines and I need have update this screen. I think about system("cls") but it not clear screen in loop. Endless loop is important.


问:
How can I use SFINAE to prevent narrowing in a template function?
I am trying to implement basic arithmetic operations for a Vector class and would like to support mixing underlying types while preventing narrowing from occurring.

```<code>template <typename T1,typename T2>
Vector<T1> operator+( Vector<T1> lhs, const Vector<T2>& rhs, std::enable_if< ! is_narrowing_conversion<T2,T1>::value >::type* = nullptr )
{ return lhs += rhs; }
</code>```

I would like to implement is_narrowing_conversion so that it will only allow the conversion if the types do not narrow. Here are some examples:

```<code>Vector<double> a = Vector<double>() + Vector<float>(); //OK
Vector<float> a = Vector<float> + Vector<double>; //Fails to find the operator+ function
</code>```

In the end I would like to write a second template operator+ function that will handle the inverse case by returning a Vector.

I found this post with an incomplete example. But it is insufficient as he notes that it disallows uint8_t to uint64_t conversions.

I also discovered Daniel Krügler's paper on fixing is_constructible. Specifically in this paper he mentions using list-initialization which already has the narrowing semantics working but I'm not sure how to convert what he mentions into a proper trait that I can use for SFINAE template deduction.

答:
Has some assumptions with respect to Vector but you should get the idea:

```<code>template <typename T1,typename T2>
Vector<typename std::common_type<T1, T2>::type>
    operator+(Vector<T1> const& lhs, Vector<T2> const& rhs)
{
    std::size_t const n = std::min(lhs.size(), rhs.size());
    Vector<typename std::common_type<T1, T2>::type> res(n);
    for(std::size_t i{}; i < n; ++i) res[i] = a[i] + b[i];
    return res;
}

Vector<double> a = Vector<double>() + Vector<float>(); // OK
Vector<double> b = Vector<float>() + Vector<double>(); // OK
</code>```

Body:
I am trying to implement basic arithmetic operations for a Vector class and would like to support mixing underlying types while preventing narrowing from occurring.

template <typename T1,typename T2>
Vector<T1> operator+( Vector<T1> lhs, const Vector<T2>& rhs, std::enable_if< ! is_narrowing_conversion<T2,T1>::value >::type* = nullptr )
{ return lhs += rhs; }

I would like to implement is_narrowing_conversion so that it will only allow the conversion if the types do not narrow. Here are some examples:

Vector<double> a = Vector<double>() + Vector<float>(); //OK
Vector<float> a = Vector<float> + Vector<double>; //Fails to find the operator+ function

In the end I would like to write a second template operator+ function that will handle the inverse case by returning a Vector.

I found this post with an incomplete example. But it is insufficient as he notes that it disallows uint8_t to uint64_t conversions.

I also discovered Daniel Krügler's paper on fixing is_constructible. Specifically in this paper he mentions using list-initialization which already has the narrowing semantics working but I'm not sure how to convert what he mentions into a proper trait that I can use for SFINAE template deduction.

Body:
Has some assumptions with respect to Vector but you should get the idea:

template <typename T1,typename T2>
Vector<typename std::common_type<T1, T2>::type>
    operator+(Vector<T1> const& lhs, Vector<T2> const& rhs)
{
    std::size_t const n = std::min(lhs.size(), rhs.size());
    Vector<typename std::common_type<T1, T2>::type> res(n);
    for(std::size_t i{}; i < n; ++i) res[i] = a[i] + b[i];
    return res;
}

Vector<double> a = Vector<double>() + Vector<float>(); // OK
Vector<double> b = Vector<float>() + Vector<double>(); // OK


问:
How to know if I am using Rails 2.3 in production?
I have a client that is running a Linux VPS with a Ruby on Rails site. There is a way to prove that the site is not running rails 2.3.14 without enter to the VPS? Something like to see if have turbolinks for example. Because turbolinks not exist in rails 2.3.14. </p>

答:
Look for the rails entry in the Gemfile.lock. It will look like this

```<code>rails (5.1.1)
  actioncable (= 5.1.1)
  ...
</code>```

The number in parentheses will indicate the version the application is using.

Body:
Look for the rails entry in the Gemfile.lock. It will look like this

rails (5.1.1)
  actioncable (= 5.1.1)
  ...

The number in parentheses will indicate the version the application is using.


问:
What is the syntax of jquery for button submit?
My code is as follows:
with button click, want to hide those paragraphs</p>

```<code><p>This is a paragraph.</p>
<p>This is another paragraph.</p>

<button>Click me to hide paragraphs</button>
</code>```

答:
```<code><!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
    $("button").click(function(){
        $("p").hide();
    });
});
</script>
</head>
<body>

<h2>This is a heading</h2>

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>

<button>Click me to hide paragraphs</button>

</body>
</html>
</code>```

Body:
My code is as follows:
with button click, want to hide those paragraphs

This is a paragraph.

This is another paragraph.

<button>Click me to hide paragraphs</button>


问:
Magento - get the custom attribute value for products in an external PHP script
does anyone know how I can get the custom attribute value for products in an PHP script (that we have in he root of the server which is used to generate XML an feed) ?

The custom attribute is property_type. Others work but not that one. Here is the code:

```<code>foreach ($arrayObj  as $row ) {
//get data
$pro_item = getPropertyItem($row['entity_id'],$pdo);
$images = getImages($row['entity_id'],$pdo);
$term = getTerm($row['entity_id'],$pdo);
$local=getLocation($row['entity_id'],$pdo);
// create tags and data
$item = $xml->createElement('item');
$i_status = $xml->createElement('status',getStatus($row['entity_id'],$pdo));
$i_propertyType = $xml->createElement('propertyType',$row['property_type']);
$i_title = $xml->createElement('title',htmlentities(removeAt($pro_item['title'])));

$i_projectName = $xml->createElement('projectName',getBuilding($local,$pro_item['title']));

$i_description = $xml->createElement('description',htmlentities(removeAt($pro_item['description'])));
</code>```

答:
Add your custom attribute property_type in the collection request with something like this :

(before loop on result)

```<code>Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect('property_type')
</code>```

Body:
does anyone know how I can get the custom attribute value for products in an PHP script (that we have in he root of the server which is used to generate XML an feed) ?

The custom attribute is property_type. Others work but not that one. Here is the code:

foreach ($arrayObj  as $row ) {
//get data
$pro_item = getPropertyItem($row['entity_id'],$pdo);
$images = getImages($row['entity_id'],$pdo);
$term = getTerm($row['entity_id'],$pdo);
$local=getLocation($row['entity_id'],$pdo);
// create tags and data
$item = $xml->createElement('item');
$i_status = $xml->createElement('status',getStatus($row['entity_id'],$pdo));
$i_propertyType = $xml->createElement('propertyType',$row['property_type']);
$i_title = $xml->createElement('title',htmlentities(removeAt($pro_item['title'])));

$i_projectName = $xml->createElement('projectName',getBuilding($local,$pro_item['title']));

$i_description = $xml->createElement('description',htmlentities(removeAt($pro_item['description'])));

Body:
Add your custom attribute property_type in the collection request with something like this :

(before loop on result)

Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect('property_type')


问:
SELECT TOP N with UNION and ORDER BY
Given the example below, why does using using UNION ALL with two SELECT TOP 5 statements in Query 2 below seemingly not respect the ORDER BY clause?

Query 1 returns the expected results but does not include the required union.
Query 2 demonstrates the unexpected behavior.
Query 3 is the workaround I'm currently using to get the desired results.

```<code>CREATE TABLE #T1 ([ID] int IDENTITY(1,1), [Description] varchar(100), [Inactive] bit);
CREATE TABLE #T2 ([ID] int IDENTITY(1,1), [Description] varchar(100), [Inactive] bit);

INSERT INTO #T1([Description], [Inactive]) VALUES ('One', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Two', 0);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Three', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Four', 0);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Five', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Six', 0);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Seven', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Eight', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Nine', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Ten', 0);

-- Query 1, works as expected giving all 4 records with Inactive = 0 plus one more
SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T1
ORDER BY [Inactive], [Description];

-- Query 2, does not work as expected, as only 2 of the Inactive = 0 records are present
SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T1
UNION ALL
SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T2
ORDER BY [Inactive], [Description];

-- Query 3, Workaround to produce desired results
WITH T1 AS (
    SELECT TOP 5 [ID], [Description], [Inactive]
    FROM #T1
    ORDER BY [Inactive], [Description]
),
T2 AS (
    SELECT TOP 5 [ID], [Description], [Inactive]
    FROM #T2
    ORDER BY [Inactive], [Description]
)
SELECT [ID], [Description], [Inactive] FROM T1
UNION ALL
SELECT [ID], [Description], [Inactive] FROM T2
ORDER BY [Inactive], [Description];

DROP TABLE #T1;
DROP TABLE #T2;
</code>```

Obviously, the workaround is working for me but I'd like to understand why Query 2 does not do what I expected it to.  In case you're wondering why I am bothering with the empty table #T2, the results are actually limited by a WHERE clause in my production example - however leaving it empty here serves the purpose of providing a comparable example without bothering to populate it.

If you do populate #T2 with the following, I find the results to be just as strange - Query 2 only gives four results with Inactive = 0.

```<code>INSERT INTO #T2([Description], [Inactive]) VALUES ('Eleven', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Twelve', 0);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Thirteen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Fourteen', 0);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Fifteen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Sixteen', 0);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Seventeen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Eighteen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Nineteen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Twenty', 0);
</code>```

I have run this script with the same results on SQL Server 2014 and SQL Server 2008 R2.

答:
A Union query works thus: execute the queries, then apply the order by clause. So with

```<code>SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T1
UNION ALL
SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T2
ORDER BY [Inactive], [Description];
</code>```

you select five arbitrarily chosen records from #T1 plus five arbitrarily chosen records from #T2 and then you order these. So you need subqueries or with clauses. E.g.:

```<code>SELECT * FROM
(
  (
    SELECT TOP 5 [ID], [Description], [Inactive]
    FROM #T1
    ORDER BY [Inactive], [Description]
  )
  UNION ALL
  (
    SELECT TOP 5 [ID], [Description], [Inactive]
    FROM #T2
    ORDER BY [Inactive], [Description]
  )
) t;
</code>```

So your workaround is not a workaround at all, but the proper query.

Title: SELECT TOP N with UNION and ORDER BY

Body:
Given the example below, why does using using UNION ALL with two SELECT TOP 5 statements in Query 2 below seemingly not respect the ORDER BY clause?

Query 1 returns the expected results but does not include the required union.
Query 2 demonstrates the unexpected behavior.
Query 3 is the workaround I'm currently using to get the desired results.

CREATE TABLE #T1 ([ID] int IDENTITY(1,1), [Description] varchar(100), [Inactive] bit);
CREATE TABLE #T2 ([ID] int IDENTITY(1,1), [Description] varchar(100), [Inactive] bit);

INSERT INTO #T1([Description], [Inactive]) VALUES ('One', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Two', 0);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Three', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Four', 0);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Five', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Six', 0);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Seven', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Eight', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Nine', 1);
INSERT INTO #T1([Description], [Inactive]) VALUES ('Ten', 0);

-- Query 1, works as expected giving all 4 records with Inactive = 0 plus one more
SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T1
ORDER BY [Inactive], [Description];

-- Query 2, does not work as expected, as only 2 of the Inactive = 0 records are present
SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T1
UNION ALL
SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T2
ORDER BY [Inactive], [Description];

-- Query 3, Workaround to produce desired results
WITH T1 AS (
    SELECT TOP 5 [ID], [Description], [Inactive]
    FROM #T1
    ORDER BY [Inactive], [Description]
),
T2 AS (
    SELECT TOP 5 [ID], [Description], [Inactive]
    FROM #T2
    ORDER BY [Inactive], [Description]
)
SELECT [ID], [Description], [Inactive] FROM T1
UNION ALL
SELECT [ID], [Description], [Inactive] FROM T2
ORDER BY [Inactive], [Description];

DROP TABLE #T1;
DROP TABLE #T2;

Obviously, the workaround is working for me but I'd like to understand why Query 2 does not do what I expected it to.  In case you're wondering why I am bothering with the empty table #T2, the results are actually limited by a WHERE clause in my production example - however leaving it empty here serves the purpose of providing a comparable example without bothering to populate it.

If you do populate #T2 with the following, I find the results to be just as strange - Query 2 only gives four results with Inactive = 0.

INSERT INTO #T2([Description], [Inactive]) VALUES ('Eleven', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Twelve', 0);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Thirteen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Fourteen', 0);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Fifteen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Sixteen', 0);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Seventeen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Eighteen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Nineteen', 1);
INSERT INTO #T2([Description], [Inactive]) VALUES ('Twenty', 0);

I have run this script with the same results on SQL Server 2014 and SQL Server 2008 R2.

Body:
A Union query works thus: execute the queries, then apply the order by clause. So with

SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T1
UNION ALL
SELECT TOP 5 [ID], [Description], [Inactive]
FROM #T2
ORDER BY [Inactive], [Description];

you select five arbitrarily chosen records from #T1 plus five arbitrarily chosen records from #T2 and then you order these. So you need subqueries or with clauses. E.g.:

SELECT * FROM
(
  (
    SELECT TOP 5 [ID], [Description], [Inactive]
    FROM #T1
    ORDER BY [Inactive], [Description]
  )
  UNION ALL
  (
    SELECT TOP 5 [ID], [Description], [Inactive]
    FROM #T2
    ORDER BY [Inactive], [Description]
  )
) t;

So your workaround is not a workaround at all, but the proper query.


答:
You actually don't need to define any arguments in the function parameters. All you need to do is access javascript's built in arguments object.

So your code could look like the following:

```<code>function test() {
    var a = arguments[0];
    var b = arguments[1];
    var c = arguments[2];

    console.log(a);
    console.log(b);
    console.log(c);
}

test("a", "b", "c");
</code>```

For reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments

Title: Pass in any number of arguments into a Javascript function

Body:
You actually don't need to define any arguments in the function parameters. All you need to do is access javascript's built in arguments object.

So your code could look like the following:

function test() {
    var a = arguments[0];
    var b = arguments[1];
    var c = arguments[2];

    console.log(a);
    console.log(b);
    console.log(c);
}

test("a", "b", "c");

For reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments


答:
You can also use pd.concat with set_index</p>

```<code>pd.concat([df1.set_index('_id'), df2.set_index('_id'), df3.set_index('_id'), df4.set_index('_id')], axis = 1).reset_index()
</code>```

Title: Python, Pandas: Merging several dataframes results in duplication of rows with uneven NaN values

Body:
I have 4 dfs, which look like below

df1

                     _id        bs        ds        as        pf
0    2017-05-01 00:00:00  0.982218  0.906662  0.614119  0.999471
1    2017-05-01 00:05:00  0.983751  0.913266  0.585237  0.999571
2    2017-05-01 00:10:00  0.983012  0.914875  0.592698  0.999631
3    2017-05-01 00:15:00  0.981884  0.910922  0.589013  0.999536
4    2017-05-01 00:20:00  0.982611  0.913082  0.601056  0.999556
5    2017-05-01 00:25:00  0.982386  0.912358  0.598856  0.999650

df2

                    _id  avg_time_serve
0   2017-05-01 00:00:00        0.520681
1   2017-05-01 00:05:00        0.521580
2   2017-05-01 00:10:00        0.517993
3   2017-05-01 00:15:00        0.520662
4   2017-05-01 00:20:00        0.514146
5   2017-05-01 00:25:00        0.513723

df3

                    _id   total_distinct_ips
0   2017-05-01 00:00:00             291094.0
1   2017-05-01 00:05:00             287922.0
2   2017-05-01 00:10:00             292103.0
3   2017-05-01 00:15:00             295675.0
4   2017-05-01 00:20:00             297813.0
5   2017-05-01 00:25:00             302406.0

df4

                    _id  total_40x  total_50x
0   2017-05-01 00:00:00     162034          0
1   2017-05-01 00:05:00     162497          0
2   2017-05-01 00:10:00     161079          0
3   2017-05-01 00:15:00     163338          0
4   2017-05-01 00:20:00     167901          0
5   2017-05-01 00:25:00     164394          0

I'm trying to combine them by '_id' column. The '_id' column is in timestamp format.

I tried using the below approaches:

**Approach 1**

from functools import reduce

dfs = [df1, df2, df3, df4]
final_df = reduce(lambda left,right: pd.merge(left, right, on='_id',
           how='outer'), dfs)

**Approach 2**
final_df = pd.Dataframe()

for df in dfs:
    if final_df.empty:
        final_df = df
    else:
        final_df = pd.merge(final_df, df, how='outer', on='_id')

Both approaches give below result:

                    _id        bs        ds        as        pf  \
0   2017-05-01 00:00:00  0.982218  0.906662  0.614119  0.999471
1   2017-05-01 00:00:00       NaN       NaN       NaN       NaN
2   2017-05-01 00:05:00  0.983751  0.913266  0.585237  0.999571
3   2017-05-01 00:05:00       NaN       NaN       NaN       NaN
4   2017-05-01 00:10:00  0.983012  0.914875  0.592698  0.999631
5   2017-05-01 00:10:00       NaN       NaN       NaN       NaN

     avg_time_serve  total_distinct_ips  total_40x  total_50x
0               NaN            291094.0     162034          0
1          0.520681            291094.0     162034          0
2               NaN            287922.0     162497          0
3          0.521580            287922.0     162497          0
4               NaN            292103.0     161079          0
5          0.517993            292103.0     161079          0

Approach 3

I took out 'df1' from dfs list, and added a 'join'.

from functools import reduce

dfs = [df2, df3, df4]
final_df = reduce(lambda left,right: pd.merge(left, right, on='_id',
           how='outer'), dfs)
final_df = final_df.join(df1.set_index('_id'), on='_id')

and finally got the right result

                    _id  avg_time_serve  total_distinct_ips  total_40x
0   2017-05-01 00:00:00        0.520681            291094.0     162034
1   2017-05-01 00:05:00        0.521580            287922.0     162497
2   2017-05-01 00:10:00        0.517993            292103.0     161079
3   2017-05-01 00:15:00        0.520662            295675.0     163338
4   2017-05-01 00:20:00        0.514146            297813.0     167901
5   2017-05-01 00:25:00        0.513723            302406.0     164394

     total_50x        bs        ds        as        pf
0            0  0.982218  0.906662  0.614119  0.999471
1            0  0.983751  0.913266  0.585237  0.999571
2            0  0.983012  0.914875  0.592698  0.999631
3            0  0.981884  0.910922  0.589013  0.999536
4            0  0.982611  0.913082  0.601056  0.999556
5            0  0.982386  0.912358  0.598856  0.999650

Question:

Shouldn't approach #1 and #2 work for any amount of dataframes merged together?

Why did approach 1 and 2 created duplicates of '_id' and insert NaN values?

Body:
You can also use pd.concat with set_index

pd.concat([df1.set_index('_id'), df2.set_index('_id'), df3.set_index('_id'), df4.set_index('_id')], axis = 1).reset_index()


问:
Data limit on Zookeeper nodes including parent and child nodes
Zookeeper documentation says the maximum allowable size of a data array is 1 MB for a node. Can I store 1MB of data under parent node and 1MB of data in all of its child nodes? </p>

<p>Ex: </p>

```<code>/parent_node
{
   1MB
}

/parent_node/child_node_1
             {
                1MB
             }

/parent_node/child_node_2
             {
                1MB
             }
</code>```

答:
Yes, you can. But it is recommended that the actual data size be much less than this limit. Keep in mind that 1MB is combined size of key and value together.

Note that zookeeper is not designed to store large amount of data since its performance seriously degrades under such circumstances.

Body:
Zookeeper documentation says the maximum allowable size of a data array is 1 MB for a node. Can I store 1MB of data under parent node and 1MB of data in all of its child nodes?

Ex:

/parent_node
{
   1MB
}

/parent_node/child_node_1
             {
                1MB
             }

/parent_node/child_node_2
             {
                1MB
             }


答:
You need to figure out the most common home town.  That is a bit challenging, but a subquery helps.  So:</p>

```<code>select avg(c.Gender = 'Female' and c.Birth_Year = 1980 and c.Cat_Hometown = ch.Cat_Hometown)
from cats c cross join
     (select c2.Cat_Hometown
      from cats c2
      group by c2.Cat_Hometown
      order by count(*) desc
      limit 1
     ) ch;
</code>```

Title: How do I calculate the percentage of a value in a column based on constraints on it , in sql?

Body:
You need to figure out the most common home town.  That is a bit challenging, but a subquery helps.  So:

select avg(c.Gender = 'Female' and c.Birth_Year = 1980 and c.Cat_Hometown = ch.Cat_Hometown)
from cats c cross join
     (select c2.Cat_Hometown
      from cats c2
      group by c2.Cat_Hometown
      order by count(*) desc
      limit 1
     ) ch;